main.c
来自「一个机器人开发的相关嵌入式开发源码」· C语言 代码 · 共 1,936 行 · 第 1/4 页
C
1,936 行
{
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
array position is unused.
*/
void label_init()
{
int t;
for(t=0; t<NUM_LAB; ++t) label_ccmd[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 */
}
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);
}/* 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);
}
i.var=toupper(*token)-'A'; /* save its index */
get_token(); /* read the equals sign */
if(*token!='=') {
serror(3);
}
get_exp(&value); /* get initial value */
vvar[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>=vvar[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 loop info */
vvar[i.var]++; /* increment control variable */
if(vvar[i.var]>i.target) return; /* all done */
fpush(i); /* otherwise, restore the info */
prog = i.loc; /* loop */
}
/* 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 form of the BASIC INPUT command */
void input()
{
char v1;
int i;
get_token(); /* see if prompt string is present */
if(token_type==QUOTE) {
uart0SendString(token); /* if so, print it and check for comma */
get_token();
if(*token!=',') serror(1);
get_token();
}
else uart0SendString("? "); /* otherwise, prompt with / */
v1 = toupper(*token)-'A'; /* get the input var */
/* REPLACE THIS CODE
scanf("%d", &i);
*/
vvar[(unsigned int)v1] = 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(char *s)
{
gtos++;
if(gtos==SUB_NEST) {
serror(12);
}
gstack[gtos]=s;
}
/* GOSUB stack pop function. */
char *gpop()
{
if(gtos==0) {
serror(13);
}
return(gstack[gtos--]);
}
/* Entry point into parser. */
void get_exp(int *result)
{
get_token();
if(!*token) {
serror(2);
}
level2(result);
putback(); /* return last token read to input stream */
}
/* display an error message */
void serror(int error)
{
static char *e[]= {
"syntax error",
"unbalanced parentheses",
"no expression present",
"equals sign expected",
"not a variable",
"LABEL list full",
"duplicate label",
"undefined label",
"THEN expected",
"TO expected",
"too many nested FOR loops",
"NEXT without FOR",
"too many nested GOSUBs",
"RETURN without GOSUB",
"invalid value"
};
uart0SendString(e[error]);
longjmp(e_buf, 1); /* return to save point */
}
/* Get a token. */
char get_token()
{
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=='\r') { /* crlf */
++prog; ++prog;
tok = EOL; *token='\r';
token[1]='\n'; token[2]=0;
return (token_type = DELIMITER);
}
if(strchr("+-*^/%=;(),><&|", *prog)){ /* delimiter */
*temp=*prog;
prog++; /* advance to next position */
temp++;
*temp=0;
return (token_type=DELIMITER);
}
if(*prog=='"') { /* quoted string */
prog++;
while(*prog!='"'&& *prog!='\r') *temp++=*prog++;
if(*prog=='\r') 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. */
void putback()
{
char *t;
t = token;
for(; *t; t++) prog--;
}
/* Look up a a token's internal representation in the
token command.
*/
int look_up(char *s)
{
int i;
char *p;
/* convert to lowercase */
p = s;
while(*p){ *p = tolower(*p); p++; }
/* see if token is in command */
for(i=0; *ccmd[i].command; i++)
if(!strcmp(ccmd[i].command, s)) return ccmd[i].tok;
return 0; /* unknown command */
}
/* Return true if c is a delimiter. */
int isdelim(char c)
{
if(strchr(" ;,+-<>/*%^=()", c) || c==9 || c=='\r' || 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;
}
/* Add or subtract two terms. */
void level2(int *result)
{
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(int *result)
{
char op;
int hold;
level4(result);
while((op = *token) == '*' || op == '/' || op == '%') {
get_token();
level4(&hold);
arith(op, result, &hold);
}
}
/* Process integer exponent. */
void level4(int *result)
{
int hold;
level5(result);
if(*token== '^') {
get_token();
level4(&hold);
arith('^', result, &hold);
}
}
/* Is a unary + or -. */
void level5(int *result)
{
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(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(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(char o, int *r, int *h)
{
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 '|':
*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;
}
}
/* Reverse 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)){
serror(4); /* not a variable */
}
return vvar[toupper(*token)-'A'];
}
#endif _BASIC_
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?