공인 인증서

Windows XP : C:\Program files\NPKI

Windows 7 : C:\Users\[사용자 계정명]\AppData\LocalLow\NPKI

Windows 8 : C:\Users\[사용자 계정명]\AppData\LocalLow\NPKI

Windows 8.1 : C:\Users\[사용자 계정명]\AppData\LocalLow\NPKI


ISP

Windows XP : C:\Windows\Application Data\VCard 

Windows 7 : C:\Users\[사용자계정명]\AppData\LocalLow\KVP\Application Data\VCard

Windows 8 : C:\Users\[사용자계정명]\AppData\LocalLow\KVP\Application Data\VCard

Windows 8.1 : C:\Users\[사용자계정명]\AppData\LocalLow\KVP\Application Data\VCard


1. 구축환경

ZigbeX 모듈 : 한백전자 HBE - ZigbeX2

개발PC : 삼성 시리즈9 울트라북 NT900X3D-A65

OS : Windows8

크로스컴파일러 : ATMEL AVR Studio 4.15

Cygwin 2.573.2.3

TinyOS2X


2. 들어가기에 앞서...

윈도우8에 지그비 개발환경을 구축하는것은 딱히 충돌문제는 일어나지 않는다.

하지만 제조사의 설명대로 진행하면 수행이 되지않기에 이와같은 글을 적는다.


3. 환경 설치 순서

(1) Cygwin 설치

(2) TinyOS2X 설치

(3) make파일 갱신

(4) AVR Stduio 설치

(5) 실습


4. 본문

(1) Cygwin 설치

앞서 구출환경에서 크로스 컴파일러는 AVR Studio라고 말하였지만 이는 hex파일을 지그비 모듈위에 올려주는 역할만을 하며 코딩은 윈도우 기반 리눅스 환경인 TinyOS2X위에서 동작한다. 이러한 TinyOS2X를 구동시키기 위한 에뮬레이터 역할을 하는것이 Cygwin이다.


한백전자에서 제공하는 CD내용을 복사해 왔다면 내용은 이와 비슷할것이다.

우선 저기 선택되어있는 Cygwin 폴더에 들어가서 setup파일을 실행해서 설치를 수행한다.

 

설치를 시작하면 이러한 화면이 나올텐데 다음으로 넘어가자


여러 방법이 있지만 이미 설치파일이 있으므로 세번째 방법을 사용하면 된다.


설치 디렉토리는 웬만하면 다음과 같이 설정하고 부가옵션은 위 그림과 같이 설정하면 된다


설치할 파일이 들어있는 위치를 설정해줘야 하는데 그 위치는 다음과 같다.

이 경우는 필자의 경우이고 각자 Cygwin 폴더내에 release폴더가 있을텐데 거기로 지정해주면 된다.


위 그림을 보면 Cygwin 폴더내에 release폴더가 있는것을 볼수있다.


위 그림과 같이 나온다면 일단 정상적인것이고 다음을 눌러 설치를 끝내면 된다.


(2) TinyOS2X 설치


TinyOS2X를 설치하기 위해 다시 한백전자가 제공하는 CD파일로 이동한다.

그 후 위에 선택되어 있는 저 폴더에 들어간다.


그 폴더 내에는 다음과 같이 두개의 파일이 있는데 모두 복사한다.


이제 Cygwin이 설치된 폴더로 이동한다. 정상적으로 진행하였다면 필자와 같이 C:\TinyOS2X 일것이다.

그리고 opt 폴더내에 방금전에 두개의 파일을 복사해야 하는데 opt폴더가 없을것이다.

그냥 폴더 새로만들기해서 같은이름으로 만들어주고 그 안에 복사한다.


그 후 Cygwin을 실행시켜서 cd /opt명령어로 opt폴더로 이동후

./Install_TinyOS2X.sh 명령어를 통해 설치한다.


이 단계 중간에 실수가 있었다면 교재에 있는데로 레지스트리 파일을 제거한후 관련폴더를 삭제해주면 되고

이미 TinyOS2X가 설치된 PC에 지그비 환경을 추가로 구축하는것은 될지 안될지는 모르겠지만

교재에 있는 방법을 참고하는것이 좋을것이다.


(3) make파일 갱신

자 이제 설치가 제대로 이루어졌는지 확인을 해봐야 한다.


Cygwin을 실행시킨후 다음 명령어를 통해 예제 소스로 이동한다.


이동후 위 그림과 같이 make zigbex 명령어를 수행시키면 다음과 같은 화면이 나와야 한다.

위와 같이 나온다면 이 챕터의 다음내용은 패스해야 한다.

그렇지 않고 에러메세지가 뜬다면 계속 진행하면 된다.

우선 cygwin은 종료하기 바란다.



make.zip


우선 위 압축파일을 다운 받아서 압축을 푼다.

그리고 c:\TinyOS2X\opt\tinyos-2.x\support 폴더로 이동한후(앞서 설치 과정에서 필자와 다른경로를 사용하였다면 앞부분에서 다소 약간의 차이가 있을수는 있다) make폴더를 삭제한후 방금 다운받은 make폴더를 붙여넣기 해준다.


그후 다시 이 챕터의 앞부분 으로 돌아가서 cygwin을 실행시킨후 예제폴더로 이동후 make명령어를 수행한후 필자와 같이 make가 정상적으로 이루어 지는지 확인하면 된다.


(4) AVR Stduio 설치 및 지그비ISP 연결

이 부분은 앞서 말한대로 make를 통해 만들어진 hex파일을 지그비 모듈에 올려주는 AVR Studio를 설치하는 파트이다. 앞서 챕터3까지의 성공유무와는 전혀무관하며 이 챕터가 제대로 된다고 앞의 과정들이 제대로 이루어졌다고 보장할수는 없고 반대로 이 챕터가 제대로 안된다고 앞의 과정에서 문제가 있었다고 할수는 없다.


우선 AVR Stduio를 설치한다.

이부분은 딱히 문제되는 부분이 없으니 그냥 알아서 하면 된다.

단 버전은 AVR Stduio 4.X 버전을 사용하길 바란다 5버전 이후로는 작동여부를 보장할수 없다.


아무튼 AVR Stduio가 설치되었다면 실행시킨다.

위와 같이 화면이 나올텐데 저 작은창은 취소해서 끄면 된다.


상단 메뉴를 보면 위에 칩같이 생기고 COM이라고 적힌 버튼이 있다.

위 그림에서는 작게 보이지만 파란색으로 선택이 되어있는 부분이다.


실행시키면 위와 같은 창이뜬다. 커넥트를 누르면 아래와 같은 창이 뜬다.

단 이 단계에서 컴퓨터에 지그비모듈이 ISP를 통해 연결되어 있어야 하고 지그비의 전원이 온 되어 있어야 한다.


ISP 모듈에 문제가 없다면 위와 같은 창이 뜰것이다. 위와 같은 창이 뜨지않고 에러가 뜬다면 높은확률로

드라이버가 제대로 안깔린것이다.


드라이버는 장치관리자에서 위그림에 활성화 되어있는 "범용 직렬 버스 컨트롤러"와 "포트"탭에 나타난다.

저렇게 모두 정상적으로 설치되어있지 않고 물음표를 나타내는 장비가 있다면 그녀석이 아마 지그비 ISP모듈 일것이므로 드라이버 업데이트를 통해 드라이버를 설치해준다.

아마 자동설치는 안될것이고 제조사CD 폴더로 가서 USB_ISP폴더내의 CDM 2.00.00폴더를 참조해 주면 될것이다.


드라이버가 정상적으로 설치된 상태에서 뜬 위와같은창에서 Fuses 탭으로 이동해보자 위와 같이 퓨즈비트가 자동으로 설정되어있다면 제대로 되는것이고.. 퓨즈비트가 비어있다면 ISP는 제대로 되는데 모듈에 문제가 있을 확률이 높다. 그리고 대부분의 경우는 배터리 부족이다. 만약 이창이 아에 뜨지 않는다면 앞서 말한대로 드라이버가 제대로 안잡힌 것이다.


(5) 실습

다시 Program탭으로 돌아와서 위 그림과 같이 Flash영역에서 HEX파일을 골라준다.

아까 앞 챕터에서 make를 통해 생성한 Blink예제를 불러온다 위치는 필자와 똑같이 수행했다면

"C:\TinyOS2X\opt\tinyos-2.x\contrib\zigbex\BlinkTimer\build\zigbex\main.hex" 이다.

예제를 불러온후 Program 버튼을 눌러주면 프로그램이 지그비 위로 올라가고 그 후 지그비에서

정상적으로 예제 프로그램이 작동하는지 확인하면 된다.


참고로 이 설명서를 작성하면서 실수한 부분이 있는데 필자는 Blank예제가 아닌 BlackTimer예제로 테스트

하였다. Black예제는 작동여부를 확인하기위해 수동으로 버튼을 계속 눌러줘야 한다는 소리를 들었기 때문이다.


5. 결론

귀찮다

 

Solutions_Logic_and_Computer_Design_Fundamentals.zip

 

Logic and Computer Design Fundamentals 3th Solutions

 

배열추가 완성본.c

내가 완성하지 못한 명령어를 포함한채로 제출 하지는 않았을테고........

분명히 최종 완성본이 있을텐데 어디있는지 모르겠음

몇년전에 만들어둔걸 올리다보니...

잘 돌아갈수도 있고....안 돌아가면 말고

-----------------------------------------------------------------------------------

 

/* A tiny BASIC interpreter */
#include <stdio.h>
#include <setjmp.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

//디버깅 하지 않을때는 주석처리한다
#define DEBUG //original code 용
#define DEBUG2 //추가 코드 용
//#define DEBUG3 //추가 코드 - 추가 함수용

#define NUM_LAB 100
#define LAB_LEN 10
#define FOR_NEST 25
#define SUB_NEST 25
#define PROG_SIZE 10000

#define DELIMITER 1
#define VARIABLE 2
#define NUMBER 3
#define COMMAND 4
#define STRING 5
#define QUOTE 6
#define ARRAY 7//(dim추가구분)

//tok
#define PRINT 1
#define INPUT 2
#define IF 3
#define THEN 4
#define FOR 5
#define NEXT 6
#define TO 7
#define GOTO 8
#define EOL 9
#define FINISHED 10
#define GOSUB 11
#define RETURN 12
#define DIM 13//(dim추가구분)
#define CLEAR 14//(clear추가구분)
#define END 15

//단일변수
char *prog; //다음에 실행할 basic 문자를 지정
jmp_buf e_buf; //PASS

char token[80]; //공백을 제외한 단어의 개수
char token_type, tok;

char *gstack[SUB_NEST]; /* stack for gosub */

int ftos; /* index to top of FOR stack */
int gtos; /* index to top of GOSUB stack */

int variables[26]={ //basic 변수 이름 부분
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0
};


//구조체
struct label
{
char name[LAB_LEN];
char *p; /* points to place to go in source file */
};
struct label label_table[NUM_LAB];

struct for_stack
{
int var; /* counter variable */
int target; /* target value */
char *loc;
} fstack[FOR_NEST]; /* stack for FOR/NEXT loop */
struct for_stack fpop();

/* keyword lookup table */
struct commands
{
char command[20];
char tok;
} table[] = { /* Commands must be entered lowercase */
{"print",PRINT}, /* in this table */
{"input",INPUT},
{"if",IF},
{"then",THEN},
{"goto",GOTO},
{"for",FOR},
{"next",NEXT},
{"to",TO},
{"gosub",GOSUB},
{"return",RETURN},
{"end",END},
{"clear", CLEAR}, //(clear추가구분)
{"dim", DIM}, //(dim추가구분)
{"",END} /* mark end of table */
};

//추가 구조체
struct arr_str //(dim추가구분)
{
int num; //배열 선언시 범위 저장
int arr_value[100]; //배열의 값 저장
int guard; //중복 선언을 막아줌
} arr_table[26]; //variable과 마찬가지로 26개 선언

//funtion - 매개변수 표시
void print();
void scan_labels();
void find_eol();
void exec_goto();
void exec_if();
void exec_for();
void next();
void fpush(struct for_stack i);
void input();
void gosub();
void greturn();
void gpush(char *s);
void label_init();

//function - 선언추가 및 매개변수 표시
int load_program(char *p, char *fname);
char get_token(void);
void putback(void);
void assignment(void);
int find_var(char *s);
int get_next_label(char *s);
int iswhite(char c);
int isdelim(char c);
int look_up(char *s);
void get_exp(int *result);
void serror(int error);
char *find_label(char *s);
char *gpop();

//추가 함수
void clear(); //변수값 초기화 함수(clear추가구분)
void assignment_arr(void); //token_type : array시 연산 (dim추가구분)
void dim(); //다차원 배열 선언(dim추가구분)

void main(int argc,char *argv[])
{
//char in[80]; no using
//int answer; no using
//char *t; no using

char *p_buf;

if(argc!=2) //프롬프트 에서 잘못 입력시
{
printf("usage: P/Gname <filename>\n");
exit(1);
}

/* allocate memory for the program */
if(!(p_buf=(char *) malloc(PROG_SIZE))) //방의 크기가 10000이 넘을때
{
printf("allocation failure");
exit(1);
}

/* load the program to execute */
if(!load_program(p_buf,argv[1])) //.bas의 문자열을 저장
{
exit(1);
}

/* initialize the long jump buffer */
if(setjmp(e_buf)) //PASS
{
exit(1);
}

prog=p_buf;

/* find the labels in the program */
scan_labels(); // 248 : L

/* initialize the FOR stack index */
ftos = 0; //전역변수

/* initialize the GOSUB stack index */
gtos = 0; //전역변수

do
{

token_type=get_token();

/* check for assignment statement */
if(token_type == VARIABLE) //변수일때
{
/*return the var to the input stream */
putback(); //전역변수 prog를 초기화

/* must be assignment statement */
assignment(); //변수 형태 오류검사 ex) A = 10
}

else if(token_type == ARRAY) //(dim추가구분)
{
putback(); //전역변수 prog를 초기화

assignment_arr(); //변수 형태 오류검사 ex) A = 10

}

/* is command */
else //변수가 아닐때 즉 명령어 일때
{
switch(tok)
{
case PRINT:
print();
break;

case GOTO:
exec_goto();
break;

case IF:
exec_if();
break;

case FOR:
exec_for();
break;

case NEXT:
next();
break;

case INPUT:
input();
break;

case GOSUB:
gosub();
break;

case RETURN:
greturn();
break;

case CLEAR:
clear();
break;

case DIM: //(dim추가구분)
dim();
break;

case END:
exit(0);

} //switch end
} //else end
} while (tok != FINISHED); //while end

} //main end

/* Load a program. */
int load_program(char *p, char *fname)
{
FILE *fp;
int i = 0;

if(!(fp=fopen(fname,"r")))
{
return 0;
}

i=0;

do
{
*p = getc(fp);
p++; i++;
} while(!feof(fp) && i<PROG_SIZE);

/* null terminate the program */
*(p-1)='\0';

fclose(fp);

return 1;
}

/* Assign a variable a value. */
void assignment(void)
{
int var, value;

/* get the variable a value */
get_token();

if(!isalpha(*token))
{
serror(4);
return;
}

var = toupper(*token)-'A';

/* get the equals sign */
get_token();

if(*token!='=')
{
serror(3);
return;
}

/* get the value to assign to var */
get_exp(&value);

/* assign the value */
variables[var] = value;
}

void assignment_arr(void) //(dim 추가구분)
{
int var, value;
int arr_temp = 0; //배열주소 (dim추가구분)

#ifdef DEBUG2
printf("assignment_arr 함수 진입 성공 \n");
#endif

/* get the variable a value */
get_token(); //배열 이름 받음

#ifdef DEBUG2
printf("assignment_arr - token(1) : %s \n",token);
#endif

if(!isalpha(*token)) //알파벳이 판단 함수
{
serror(4);
return;
}

var = toupper(*token)-'A'; //대문자로 변환(내장함수)

get_token(); //'(' 받음

#ifdef DEBUG2
printf("assignment_arr - token(2) : %s \n",token);
#endif

if(*token!='(')
{
serror(14);
return;
}

get_token(); //숫자 받음

if(token_type == NUMBER)
{
arr_temp = atoi(token); //c문법대로라면 현행 베이직 문법대로라면 + 1을 해야함

if(arr_table[var].num < arr_temp) //선언한 배열값을 넘을경우
{
serror(18);
return;
}
}

else //만약 숫자가 아닐경우
{
#ifdef DEBUG2
printf("assignment_arr - serror(17) - token : %s \n",token);
#endif

serror(17);
return;
}

get_token();

#ifdef DEBUG2
printf("assignment_arr - token(3) : %s \n",token);
#endif

if(*token!=')')
{
serror(15);
return;
}

get_token();

if(*token!='=')
{
serror(3);
return;
}

get_exp(&value);

arr_table[var].arr_value[arr_temp] = value;

#ifdef DEBUG2
printf("assignment_arr - var : %d \n",var);
printf("assignment_arr - arr_table[%d].arr_value[%d] : %d \n",var, arr_temp,
arr_table[var].arr_value[arr_temp]);
#endif

}


/* Execute a simple version of the BASIC PRINT statement */
void print()
{
int answer;
int len=0,spaces;
char last_delim;

do
{
/* get next list item */
get_token();

if(tok==EOL || tok==FINISHED)
{
break;
}

/* is string */
if(token_type==QUOTE)
{
printf(token);
len += strlen(token);
get_token();
}

/* is expression */
else
{
putback();

#ifdef DEBUG
printf("PRINT 내부 get_exp 함수 진입 \n");
#endif

get_exp(&answer);

get_token();
len += printf("%d",answer);
}

last_delim = *token;

if(*token==';')
{
/* compute number of spaces to move to next tab */
spaces = 8 - (len % 8);

/* add in the tabbing position */
len += spaces;

while(spaces)
{
printf(" ");
spaces--;
}
}

/* do nothing */
else if(*token==',');

else if(tok!=EOL && tok!=FINISHED)
{
#ifdef DEBUG
printf("print(1) - serror(0); \n");
#endif

serror(0);
}

} while (*token==';' || *token==','); //do-while end

if(tok==EOL || tok==FINISHED)
{
if(last_delim != ';' && last_delim != ',')
{
printf("\n");
}
}

/* error is not,or; */
else
{
#ifdef DEBUG
printf("print(1) - serror(0); \n");
#endif

serror(0);
}


} //function end

/* Find all labels. */
void scan_labels()
{
int addr;
char *temp;

/* zero all labels */
label_init();

/* save pointer to top of program */
temp = prog;

/* if the first token in the file is a label */
get_token();

if(token_type==NUMBER)
{
strcpy(label_table[0].name,token);
label_table[0].p=prog;
}

find_eol();

do
{
get_token();
if(token_type==NUMBER)
{
addr = get_next_label(token);

if(addr== -1 || addr== -2)
{
(addr== -1) ?serror(5):serror(6);
}

strcpy(label_table[addr].name,token);

/* current point in program */
label_table[addr].p=prog;

} //if end

/* if not on a blank line,find next line */
if(tok!=EOL)
{
find_eol();
}

} while(tok!=FINISHED); //do-while end

/* restore to original */
prog = temp;

} //function end

/* Find the start of next line */
void find_eol()
{
while(*prog!='\n' && *prog!='\0')
{
++prog;
}

if(*prog)
{
prog++;
}

}

/*
Return index of next free position in label array.
A -1 is returned if the array is full.
A -2 is returned when duplicate label is found.
*/
int get_next_label(char *s)
{
register int t;

for(t=0; t<NUM_LAB; ++t)
{
if(label_table[t].name[0]==0)
{
return t;
}

/* dup */
if(!strcmp(label_table[t].name,s))
{
return -2;
}
}

return -1;
}

/* Find location of given label. A null is returned if
label is not found; otherwise a pointer to the position
of the label is returned */
char *find_label(char *s)
{
register int t;

for(t=0; t<NUM_LAB; ++t)
{
if(!strcmp(label_table[t].name,s))
{
return label_table[t].p;
}
}

/* error condition */
return '\0';
}

/* Execute a GOTO statement. */
void exec_goto()
{
char *loc;

/* get label to go to */
get_token();

/* find the location of the label */
loc = find_label(token);

if(loc=='\0')
{
/* label not defined */
serror(7);
}

/* start program running at that loc */
else
{
prog=loc;
}
}

/* Initialize the array that holds the labels.
By convention,a null label name indicates that */
void label_init()
{
register int t;

for(t=0; t<NUM_LAB; ++t)
{
label_table[t].name[0]='\0';
}
}

/* Execute an IF statement. */
void exec_if()
{
int x,y,cond;
char op;

/* get left expression */
get_exp(&x);

/* get the operator */
get_token();

if(!strchr("=<>",*token))
{
#ifdef DEBUG
printf("exec_if - serror(0); \n");
#endif

/* not a legal operator */
serror(0);
return;
}

op = *token;

/* get right expression */
get_exp(&y);

/* determine the outcome */
cond = 0;

switch(op)
{
case '<':
if(x<y)
{
cond=1;
}
break;

case '>':
if(x>y)
{
cond=1;
}
break;

case '=':
if(x==y)
{
cond=1;
}
break;
}

/* is true so process target of IF */
if(cond)
{
get_token();

/* else program execution starts on next line */
if(tok!=THEN)
{
serror(8);
return;
}
}

/* find start of next line */
else
{
find_eol();
}

} //function end

/* Execute a for loop */
void exec_for()
{
struct for_stack i;
int value;

/* read the control variable */
get_token();

if(!isalpha(*token))
{
serror(4);
return;
}

/* save its index */
i.var=toupper(*token)-'A';

/* read the equal sign */
get_token();

if(*token!='=')
{
serror(3);
return;
}

/* get initial value */
get_exp(&value);

variables[i.var]=value;

get_token();

/* read and discard the TO */
if(tok!=TO)
{
serror(9);
}

/* get target value */
get_exp(&i.target);

/* if loop can execute at least once,push info on stack */
if(value>=variables[i.var])
{
i.loc = prog;
fpush(i);
}

/* otherwise,skip loop code altogether */
else
{
while(tok!=NEXT)
{
get_token();
}
}

}

/* Execute a NEXT statement. */
void next()
{
struct for_stack i;

/* read the info */
i=fpop();

/* increment control variable */
variables[i.var]++;

if(variables[i.var]>i.target)
{
/* all don */
return;
}

/* otherwise, restore the info */
fpush(i);

/* loop */
prog = i.loc;
}

/* Push function for the FOR stack */
void fpush(struct for_stack i)
{
if(ftos>FOR_NEST)
{
serror(10);
}

fstack[ftos]=i;
ftos++;
}

struct for_stack fpop()
{
ftos--;

if(ftos<0)
{
serror(11);
}

return(fstack[ftos]);
}

/* Execute a simple from of the BASIC INPUT command */
void input()
{
//char str[80]; no using***********************
char var;
int i;

/* see if prompt string is present */
get_token();

if(token_type==QUOTE)
{
/* if so,print it and check for comma */
printf(token);
get_token();

if(*token!=',')
{
serror(1);
}

get_token();
}

else
{
/* otherwise,prompt with / */
printf("? ");
}

/* get the input var */
var = toupper(*token)-'A';

/*read input */
scanf("%d",&i);

/* store it */
variables[var] = i;
}

/* Execute a GOSUB command. */
void gosub()
{
char *loc;

get_token();

/* find the label to call */
loc = find_label(token);

if(loc=='\0')
{
/* label not defined */
serror(7);
}

else
{
/* save place to return to */
gpush(prog);
/* start program running at that loc */
prog = loc;
}
}

/* Return from GOSUB */
void greturn()
{
prog = gpop();
}

/* GOSUB stack push function. */
void gpush(char *s)
{
gtos++;

if(gtos==SUB_NEST)
{
serror(12);
return;
}

gstack[gtos]=s;
}

/* GOSUB stack pop function. */
char *gpop()
{
if(gtos==0)
{
serror(13);
return 0;
}

return(gstack[gtos--]);
}

/* recursive descent parser for integer expressions
which may include variables */
#define DELIMITER 1
#define VARIABLE 2
#define NUMBER 3
#define COMMAND 4
#define STRING 5
#define QUOTE 6

#define EOL 9
#define FINISHED 10

void level2(),level3(),level4(),level5();
void level6(),primitive(),arith(),unary();

/* Entry point into parser. */
void get_exp(int *result)
{
get_token();

#ifdef DEBUG
printf("get_exp - token : %s \n",token);
#endif

if(! *token)
{
serror(2);
return;
}

level2(result);
putback();
}

/* Add or subtract two terms. */
void level2(int *result)
{
register char op;
int hold;

level3(result);

while((op = *token) == '+' || op == '-')
{
get_token();

#ifdef DEBUG
printf("level2 - token : %s \n",token);
#endif

level3(&hold);
arith(op,result,&hold);
}
}

/* Multiply or divide two factors. */
void level3(int *result)
{
register char op;
int hold;

level4(result);
while((op = *token) == '*' || op == '/' || op == '%')
{
get_token();

#ifdef DEBUG
printf("level3 - token : %s \n",token);
#endif

level4(&hold);
arith(op,result,&hold);
}
}

/* Process integer exponent. */
void level4(int *result)
{
int hold;

level5(result);

if(*token == '^')
{
get_token();

#ifdef DEBUG
printf("level4 - token : %s \n",token);
#endif

level4(&hold);
arith('^',result,&hold);
}

}

/* Is a unary + or -. */
void level5(int *result)
{
register char op;

op = 0;

if((token_type==DELIMITER) && *token == '+' || *token == '-')
{
op = *token;
get_token();

#ifdef DEBUG
printf("level5 - token : %s \n",token);
#endif

}

level6(result);

if(op)
{
unary(op,result);
}
}

/* Process parenthesized expression. */
void level6(int *result)
{
if((*token == '(') && (token_type == DELIMITER))
{
get_token();

#ifdef DEBUG
printf("level6 - token(1) : %s \n",token);
#endif

level2(result);

if(*token != ')')
{
serror(1);
}

get_token();

#ifdef DEBUG
printf("level6 - token(2) : %s \n",token);
#endif

}

else
{
primitive(result);
}
}

/* Find value of number or variable. */
void primitive(int *result)
{
int v_t=0;
int a_t=0;

switch(token_type)
{
case VARIABLE:

#ifdef DEBUG
printf("primitive case VARIABLE 진입 \n");
#endif

*result = find_var(token);
get_token();

#ifdef DEBUG
printf("primitive - token(1) : %s \n",token);
#endif

return;

case NUMBER:
*result = atoi(token);
get_token();

#ifdef DEBUG
printf("primitive - token(2) : %s \n",token);
#endif

return;

case ARRAY:
v_t = toupper(*token)-'A';
get_token(); //"(" get

get_token(); //배열주소 get
a_t = atoi(token);

get_token(); //")" get

*result = arr_table[v_t].arr_value[a_t];

get_token();

return;

default:
#ifdef DEBUG
printf("primitive - serror(0) token : %s \n",token);
#endif

serror(0);

}
}

/* Perform the specified arithmetic. */
void arith(char o, int *r, int *h)
{
register int t, ex;

switch(o)
{
case '-':
*r = *r - *h;
break;

case '+':
*r = *r + *h;
break;

case '*':
*r = *r * *h;
break;

case '/':
*r = (*r) / (*h);
break;

case '%':
t = (*r) / (*h);
*r = *r - (t*(*h));
break;

case '^':
ex = *r;

if(*h == 0)
{
*r = 1;
break;
}

for(t = *h-1; t>0; --t)
{
*r= (*r) * ex;
}

break;
}
}

/* Reverce the sign. */
void unary(char o, int *r)
{
if(o == '-')
{
*r = -(*r);
}
}

/* Find the value of a variable */
int find_var(char *s)
{
if(!isalpha(*s))
{
#ifdef DEBUG
printf("find_var - serror(4) \n");
#endif

/* not a variable */
serror(4);
return 0;
}

return variables[toupper(*token) - 'A'];
}

/* Display an error message */
void serror(int error)
{
static char *e[] = {
"syntex error", //0
"unbalenced parentheses", //1
"no expression present", //2
"equal sign expected", //3
"not a variable", //4
"label table full", //5
"duplicate label", //6
"undefined label", //7
"THEN expected", //8
"TO expected", //9
"too many nested FOR loops", //10
"NEXT without FOR", //11
"too many nested GOSUBs", //12
"RETURN without GOSUB", //13
"'(' is a requisite", //14 (dim추가구분)
"')' is a requisite", //15 (dim추가구분)
"array limited 99", //16 (dim추가구분)
"not a number", //17 (dim추가구분)
"over array size", //18 (dim추가구분)
"declare already" //19 (dim추가구분)
};

printf("%s\n",e[error]);

/* return to save point */
longjmp(e_buf,1);
}

/* Get a token. */
char get_token(void)
{
register char *temp;

token_type=0; tok=0;
temp = token;

/* end of file */
if(*prog == '\0')
{
*token = 0;
tok = FINISHED;
return(token_type=DELIMITER);
}

/* skip over white space */
while(iswhite(*prog))
{
++prog;
}

/* crLf */
if(*prog=='\n')
{
++prog;
tok = EOL; *token='\n';
token[1]='\0';
return(token_type = DELIMITER);
}

/* delimiter */
if(strchr("+-*^/%=;(),><",*prog))
{
*temp = *prog;
/* advanced to next position */
prog++;
temp++;
*temp=0;
return(token_type=DELIMITER);
}

/* quoted string */
if(*prog=='"')
{
prog++;

while(*prog!='"' && *prog!='\n')
{
*temp++ = *prog++;
}

if(*prog=='\n')
{
serror(1);
}

prog++; *temp=0;
return(token_type=QUOTE);
}

/* number */
if(isdigit(*prog))
{
while(!isdelim(*prog))
{
*temp++ = *prog++;
}

*temp='\0';
return(token_type=NUMBER);
}

/* var or command */
if(isalpha(*prog))
{
while(!isdelim(*prog))
{
*temp++ = *prog++;
}

token_type=STRING;
}

*temp='\0';

/* see if a string is a command or a variable */
if(token_type==STRING)
{
/* convert to internal rep */
tok=look_up(token);

if(*prog++ == '(') //(dim추가구분)
{
#ifdef DEBUG2
printf("token_type : ARRAY 부여 \n");
#endif

token_type=ARRAY;
*prog--;
}

else if(!tok)
{
#ifdef DEBUG
printf("token_type : VARIABLE 부여 \n");
#endif

token_type=VARIABLE;
}

/* is a command */
else
{
token_type=COMMAND;
}
}
return token_type;
}

/* Return a token to input stream. */
void putback(void)
{
char *t;

t = token;
for(; *t; t++)
{
prog--;
}
}

/* Look up a token's internal representation in the
token table */
int look_up(char *s)
{
register int i;//,j; no using************************
char *p;

/* convert to lowercase */
p = s;

while(*p)
{
*p = tolower(*p); p++;
}

/* see if token is in table */
for(i=0; *table[i].command; i++)
{
if(!strcmp(table[i].command,s))
{
return table[i].tok;
}
}

/* unknown command */
return 0;
}

/* Return true if c is a delimiter. */
int isdelim(char c)
{
if(strchr(" ;,+-<>/*%^=()",c) || c==9 || c=='\n' || c==0)
{
return 1;
}

return 0;
}

/* Return 1 if c is space or tab */
int iswhite(char c)
{
if(c==' ' || c=='\t')
{
return 1;
}

else return 0;
}

void clear(void)//보류
{
int count1, count2;

printf("clear all data & memory \n");

for(count1 = 0; count1<80; count1++)
{
token[count1] = '0';
}

//*prog = '0'; //다음에 실행할 basic 문자를 지정
//token_type = '0';
//tok = '0';

//char *gstack[SUB_NEST]; /* stack for gosub */

ftos=0; /* index to top of FOR stack */
gtos=0; /* index to top of GOSUB stack */
/*
for(count1 = 0; count1<26; count1++)
{
variables[count1] = 0;
}
*/

for(count1 = 0; count1<100; count1++)
{
//*label_table[count1].p = '0';
//label_table[count1].p++;

for(count2 = 0; count2<10; count2++)
{
label_table[count1].name[count2] = '0';
}

}

/*
for(count1 = 0; count1<25; count1++)
{
fstack[count1].var = 0;
fstack[count1].target = 0;
*fstack[count1].loc = '0';
}
*/

}


void dim(void) //(dim추가구분)
{
int var;

get_token(); //배열이름

if(!isalpha(*token)) //알파벳이 판단 함수
{
serror(4);
return;
}

var = toupper(*token)-'A';

if(arr_table[var].guard)
{
serror(18);
return;
}

else
{
arr_table[var].guard = 1;
}

get_token(); //'(' 받음

if(*token!='(')
{
serror(14);
return;
}

get_token(); //숫자 받음

if(token_type == NUMBER)
{
arr_table[var].num = atoi(token); //c문법대로라면 현행 베이직 문법대로라면 + 1을 해야함
}

else //만약 숫자가 아닐경우
{
#ifdef DEBUG2
printf("dim - serror(17) - token : %s \n",token);
#endif

serror(17);
return;
}

get_token(); //')'받음

if(*token!=')')
{
serror(15);
return;
}


}

/*
1. clear 명령어 완성못함

3. 동적 메모리 할당으로 배열길이 자유조절하기
*/

 

 

mybasic.c

비주얼 베이직 코드를 수행하는 인터프리터

-----------------------------------------------------------------------------------

/* A tiny BASIC interpreter */
#include "stdio.h"
#include "setjmp.h"
#include "math.h"
#include "ctype.h"
#include "stdlib.h"

#define NUM_LAB 100
#define LAB_LEN 10
#define FOR_NEST 25
#define SUB_NEST 25
#define PROG_SIZE 10000

#define DELIMITER 1
#define VARIABLE 2
#define NUMBER 3
#define COMMAND 4
#define STRING 5
#define QUOTE 6

#define PRINT 1
#define INPUT 2
#define IF 3
#define THEN 4
#define FOR 5
#define NEXT 6
#define TO 7
#define GOTO 8
#define EOL 9
#define FINISHED 10
#define GOSUB 11
#define RETURN 12
#define END 13

char *prog; /* holds expression to be analyzed */
jmp_buf e_buf; /* hold environment for longjmp() */

int variables[26]={ /* 26 user variables, A-Z */
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0
};

struct commands { /* keyword lookup table */
char command[20];
char tok;
} table[] = { /* Commands must be entered lowercase */
"print",PRINT, /* in this table */
"input",INPUT,
"if",IF,
"then",THEN,
"goto",GOTO,
"for",FOR,
"next",NEXT,
"to",TO,
"gosub",GOSUB,
"return",RETURN,
"end",END,
"",END /* mark end of table */
};

char token[80];
char token_type,tok;

struct label {
char name[LAB_LEN];
char *p; /* points to place to go in source file */
};
struct label label_table[NUM_LAB];

char *find_label(), *gpop();

struct for_stack {
int var; /* counter variable */
int target; /* target value */
char *loc;
} fstack[FOR_NEST]; /* stack for FOR/NEXT loop */
struct for_stack fpop();

char *gstack[SUB_NEST]; /* stack for gosub */

int ftos; /* index to top of FOR stack */
int gtos; /* index to top of GOSUB stack */

void print(),scan_labels(),find_eol(),exec_goto();
void exec_if(),exec_for(),next(),fpush(),input();
void gosub(),greturn(),gpush(),label_init();

main(argc,argv)
int argc;
char *argv[];
{
char in[80];
int answer;
char *p_buf;
char *t;

if(argc!=2) {
printf("usage: run <filename>\n");
exit(1);
}

/* allocate memory for the program */
if(!(p_buf=(char *) malloc(PROG_SIZE))) {
printf("allocation failure");
exit(1);
}

/* load the program to execute */
if(!load_program(p_buf,argv[1])) exit(1);

if(setjmp(e_buf)) exit(1); /* initialize the long jump buffer */

prog=p_buf;
scan_labels(); /* find the labels in the program */
ftos = 0; /* initialize the FOR stack index */
gtos = 0; /* initialize the GOSUB stack index */
do {
token_type=get_token();
/* check for assignment statement */
if(token_type == VARIABLE) {
putback(); /*return the var to the input stream */
assignment(); /* must be assignment statement */
}
else /* is command */
switch(tok) {
case PRINT:
print();
break;
case GOTO:
exec_goto();
break;
case IF:
exec_if();
break;
case FOR:
exec_for();
break;
case NEXT:
next();
break;
case INPUT:
input();
break;
case GOSUB:
gosub();
break;
case RETURN:
greturn();
break;
case END:
exit(0);
}
} while (tok != FINISHED);
}

/* Load a program. */
load_program(p,fname)
char *p;
char *fname;
{
FILE *fp;
int i = 0;

if(!(fp=fopen(fname,"r"))) return 0;

i=0;
do {
*p = getc(fp);
p++; i++;
} while(!feof(fp) && i<PROG_SIZE);
*(p-1)='\0'; /* null terminate the program */
fclose(fp);
return 1;
}

/* Assign a variable a value. */
assignment()
{
int var, value;

/* get the variable a value */
get_token();
if(!isalpha(*token)) {
serror(4);
return;
}

var = toupper(*token)-'A';

/* get the equals sign */
get_token();
if(*token!='=') {
serror(3);
return;
}

/* get the value to assign to var */
get_exp(&value);

/* assign the value */
variables[var] = value;
}

/* Execute a simple version of the BASIC PRINT statement */
void print()
{
int answer;
int len=0,spaces;
char last_delim;

do {
get_token(); /* get next list item */
if(tok==EOL || tok==FINISHED) break;
if(token_type==QUOTE) { /* is string */
printf(token);
len += strlen(token);
get_token();
}
else { /* is expression */
putback();
get_exp(&answer);
get_token();
len += printf("%d",answer);
}
last_delim = *token;

if(*token==';') {
/* compute number of spaces to move to next tab */
spaces = 8 - (len % 8);
len += spaces; /* add in the tabbing position */
while(spaces) {
printf(" ");
spaces--;
}
}
else if(*token==','); /* do nothing */
else if(tok!=EOL && tok!=FINISHED) serror(0);
} while (*token==';' || *token==',');

if(tok==EOL || tok==FINISHED) {
if(last_delim != ';' && last_delim != ',') printf("\n");
}
else serror(0); /* error is not,or; */
}

/* Find all labels. */
void scan_labels()
{
int addr;
char *temp;

label_init(); /* zero all labels */
temp = prog; /* save pointer to top of program */

/* if the first token in the file is a label */
get_token();
if(token_type==NUMBER) {
strcpy(label_table[0].name,token);
label_table[0].p=prog;
}

find_eol();
do {
get_token();
if(token_type==NUMBER) {
addr = get_next_label(token);
if(addr== -1 || addr== -2) {
(addr== -1) ?serror(5):serror(6);
}
strcpy(label_table[addr].name,token);
label_table[addr].p=prog; /* current point in program */
}
/* if not on a blank line,find next line */
if(tok!=EOL) find_eol();
} while(tok!=FINISHED);
prog = temp; /* restore to original */
}

/* Find the start of next line */
void find_eol()
{
while(*prog!='\n' && *prog!='\0') ++prog;
if(*prog) prog++;
}

/* Return index of next free position in label array.
A -1 is returned if the array is full.
A -2 is returned when duplicate label is found.
*/
get_next_label(s)
char *s;
{
register int t;

for(t=0; t<NUM_LAB; ++t) {
if(label_table[t].name[0]==0) return t;
if(!strcmp(label_table[t].name,s)) return -2; /* dup */
}

return -1;
}

/* Find location of given label. A null is returned if
label is not found; otherwise a pointer to the position
of the label is returned */
char *find_label(s)
char *s;
{
register int t;

for(t=0; t<NUM_LAB; ++t)
if(!strcmp(label_table[t].name,s)) return label_table[t].p;
return '\0'; /* error condition */
}

/* Execute a GOTO statement. */
void exec_goto()
{
char *loc;

get_token(); /* get label to go to */
/* find the location of the label */
loc = find_label(token);
if(loc=='\0')
serror(7); /* label not defined */

else prog=loc; /* start program running at that loc */
}

/* Initialize the array that holds the labels.
By convention,a null label name indicates that */
void label_init()
{
register int t;

for(t=0; t<NUM_LAB; ++t) label_table[t].name[0]='\0';
}

/* Execute an IF statement. */
void exec_if()
{
int x,y,cond;
char op;

get_exp(&x); /* get left expression */

get_token(); /* get the operator */
if(!strchr("=<>",*token)) {
serror(0); /* not a legal operator */
return;
}
op=*token;

get_exp(&y); /* get right expression */

/* determine the outcome */
cond = 0;
switch(op) {
case '<':
if(x<y) cond=1;
break;
case '>':
if(x>y) cond=1;
break;
case '=':
if(x==y) cond=1;
break;
}
if(cond) { /* is true so process target of IF */
get_token();
if(tok!=THEN) {
serror(8);
return;
} /* else program execution starts on next line */
}
else find_eol(); /* find start of next line */
}

/* Execute a for loop */
void exec_for()
{
struct for_stack i;
int value;

get_token(); /* read the control variable */
if(!isalpha(*token)) {
serror(4);
return;
}

i.var=toupper(*token)-'A'; /* save its index */

get_token(); /* read the equal sign */
if(*token!='=') {
serror(3);
return;
}

get_exp(&value); /* get initial value */

variables[i.var]=value;

get_token();
if(tok!=TO) serror(9); /* read and discard the TO */

get_exp(&i.target); /* get target value */

/* if loop can execute at least once,push info on stack */
if(value>=variables[i.var]) {
i.loc = prog;
fpush(i);
}
else /* otherwise,skip loop code altogether */
while(tok!=NEXT) get_token();
}

/* Execute a NEXT statement. */
void next()
{
struct for_stack i;

i=fpop(); /* read the info */

variables[i.var]++; /* increment control variable */
if(variables[i.var]>i.target) return; /* all don */
fpush(i); /* otherwise, restore the info */
prog = i.loc; /* loop */
}

/* Push function for the FOR stack */
void fpush(i)
struct for_stack i;
{
if(ftos>FOR_NEST)
serror(10);

fstack[ftos]=i;
ftos++;
}

struct for_stack fpop()
{
ftos--;
if(ftos<0) serror(11);
return(fstack[ftos]);
}

/* Execute a simple from of the BASIC INPUT command */
void input()
{
char str[80],var;
int i;

get_token(); /* see if prompt string is present */
if(token_type==QUOTE) {
printf(token); /* if so,print it and check for comma */
get_token();
if(*token!=',') serror(1);
get_token();
}
else printf("? "); /* otherwise,prompt with / */
var = toupper(*token)-'A'; /* get the input var */

scanf("%d",&i); /*read input */

variables[var] = i; /* store it */
}

/* Execute a GOSUB command. */
void gosub()
{
char *loc;

get_token();
/* find the label to call */
loc = find_label(token);
if(loc=='\0')
serror(7); /* label not defined */
else {
gpush(prog); /* save place to return to */
prog = loc; /* start program running at that loc */
}
}

/* Return from GOSUB */
void greturn()
{
prog = gpop();
}

/* GOSUB stack push function. */
void gpush(s)
char *s;
{
gtos++;

if(gtos==SUB_NEST) {
serror(12);
return;
}

gstack[gtos]=s;
}

/* GOSUB stack pop function. */
char *gpop()
{
if(gtos==0) {
serror(13);
return 0;
}
return(gstack[gtos--]);
}
/* recursive descent parser for integer expressions
which may include variables */

#define DELIMITER 1
#define VARIABLE 2
#define NUMBER 3
#define COMMAND 4
#define STRING 5
#define QUOTE 6

#define EOL 9
#define FINISHED 10

void level2(),level3(),level4(),level5();
void level6(),primitive(),arith(),unary();

/* Entry point into parser. */
get_exp(result)
int *result;
{
get_token();
if(! *token) {
serror(2);
return;
}
level2(result);
putback();
}
/* Add or subtract two terms. */
void level2(result)
int *result;
{
register char op;
int hold;

level3(result);
while((op = *token) == '+' || op == '-') {
get_token();
level3(&hold);
arith(op,result,&hold);
}
}

/* Multiply or divide two factors. */
void level3(result)
int *result;
{
register char op;
int hold;

level4(result);
while((op = *token) == '*' || op == '/' || op == '%') {
get_token();
level4(&hold);
arith(op,result,&hold);
}
}

/* Process integer exponent. */
void level4(result)
int *result;
{
int hold;

level5(result);
if(*token == '^') {
get_token();
level4(&hold);
arith('^',result,&hold);
}

}

/* Is a unary + or -. */
void level5(result)
int *result;
{
register char op;

op = 0;
if((token_type==DELIMITER) && *token == '+' || *token == '-') {
op = *token;
get_token();
}
level6(result);
if(op)
unary(op,result);
}

/* Process parenthesized expression. */
void level6(result)
int *result;
{
if((*token == '(') && (token_type == DELIMITER)) {
get_token();
level2(result);
if(*token != ')')
serror(1);
get_token();
}
else
primitive(result);
}

/* Find value of number or variable. */
void primitive(result)
int *result;
{
switch(token_type) {
case VARIABLE:
*result = find_var(token);
get_token();
return;
case NUMBER:
*result = atoi(token);
get_token();
return;
default:
serror(0);
}
}

/* Perform the specified arithmetic. */
void arith(o,r,h)
char o;
int *r, *h;
{
register int t, ex;

switch(o) {
case '-':
*r = *r - *h;
break;
case '+':
*r = *r + *h;
break;
case '*':
*r = *r * *h;
break;
case '/':
*r = (*r) / (*h);
break;
case '%':
t = (*r) / (*h);
*r = *r - (t*(*h));
break;
case '^':
ex = *r;
if(*h == 0) {
*r = 1;
break;
}
for(t = *h-1; t>0; --t) *r= (*r) * ex;
break;
}
}
/* Reverce the sign. */
void unary(o,r)
char o;
int *r;
{
if(o == '-') *r = -(*r);
}

/* Find the value of a variable */
int find_var(s)
char *s;
{
if(!isalpha(*s)) {
serror(4); /* not a variable */
return 0;
}
return variables[toupper(*token) - 'A'];
}

/* Display an error message */
serror(error)
int error;
{
static char *e[] = {
"syntex error",
"unbalenced parentheses",
"no expression present",
"equal sign expected",
"not a variable",
"label table full",
"duplicate label",
"undefined label",
"THEN expected",
"TO expected",
"too many nested FOR loops",
"NEXT without FOR",
"too many nested GOSUBs",
"RETURN without GOSUB"
};
printf("%s\n",e[error]);
longjmp(e_buf,1); /* return to save point */
}

/* Get a token. */
get_token()
{
register char *temp;

token_type=0; tok=0;
temp = token;
if(*prog == '\0') { /* end of file */
*token = 0;
tok = FINISHED;
return(token_type=DELIMITER);
}

while(iswhite(*prog)) ++prog; /* skip over white space */

if(*prog=='\n') { /* crLf */
++prog;
tok = EOL; *token='\n';
token[1]='\0';
return(token_type = DELIMITER);
}

if(strchr("+-*^/%=;(),><",*prog)) { /* delimiter */
*temp = *prog;
prog++; /* advanced to next position */
temp++;
*temp=0;
return(token_type=DELIMITER);
}

if(*prog=='"') { /* quoted string */
prog++;
while(*prog!='"' && *prog!='\n') *temp++ = *prog++;
if(*prog=='\n') serror(1);
prog++; *temp=0;
return(token_type=QUOTE);
}

if(isdigit(*prog)) { /* number */
while(!isdelim(*prog)) *temp++ = *prog++;
*temp='\0';
return(token_type=NUMBER);
}

if(isalpha(*prog)) { /* var or command */
while(!isdelim(*prog)) *temp++ = *prog++;
token_type=STRING;
}

*temp='\0';

/* see if a string is a command or a variable */
if(token_type==STRING) {
tok=look_up(token); /* convert to internal rep */
if(!tok) token_type=VARIABLE;
else token_type=COMMAND; /* is a command */
}
return token_type;
}

/* Return a token to input stream. */
putback()
{
char *t;

t = token;
for(; *t; t++) prog--;
}

/* Look up a token's internal representation in the
token table */
look_up(s)
char *s;
{
register int i,j;
char *p;

/* convert to lowercase */
p = s;
while(*p){ *p = tolower(*p); p++; }

/* see if token is in table */
for(i=0; *table[i].command; i++)
if(!strcmp(table[i].command,s)) return table[i].tok;
return 0; /* unknown command */
}

/* Return true if c is a delimiter. */
isdelim(c)
char c;
{
if(strchr(" ;,+-<>/*%^=()",c) || c==9 || c=='\n' || c==0)
return 1;
return 0;
}

/* Return 1 if c is space or tab */
iswhite(c)
char c;
{
if(c==' ' || c=='\t') return 1;
else return 0;
}

 

+ Recent posts