/* Get function parameters. */ void get_params(void) { struct var_type *p; int i; i = lvartos-1; do { /* process comma-separated list of parameters */ get_token(); p = &local_var_stack[i]; if(*token != ')' ) { if(tok != INT && tok != CHAR) sntx_err(TYPE_EXPECTED); p->v_type = token_type; get_token(); /* link parameter name with argument already on local var stack */ strcpy(p->var_name, token); get_token(); i--; } else break; } while(*token == ','); if(*token != ')') sntx_err(PAREN_EXPECTED); }
/* Execute a for loop. */ void exec_for(void) { int cond; char *temp, *temp2; int brace ; get_token(); eval_exp(&cond); /* initialization expression */ if(*token != ';') sntx_err(SEMI_EXPECTED); prog++; /* get past the ; */ temp = prog; for(;;) { eval_exp(&cond); /* check the condition */ if(*token != ';') sntx_err(SEMI_EXPECTED); prog++; /* get past the ; */ temp2 = prog; /* find the start of the for block */ brace = 1; while(brace) { get_token(); if(*token == '(') brace++; if(*token == ')') brace--; } if(cond) interp_block(); /* if true, interpret */ else { /* otherwise, skip around loop */ find_eob(); return; } prog = temp2; eval_exp(&cond); /* do the increment */ prog = temp; /* loop back to top */ } }
void exec_for() { int cond; char *temp, *temp2; int brace ; get_token(); eval_exp(&cond); if(*token!=';') sntx_err(SEMI_EXPECTED); prog++; temp = prog; for(;;) { eval_exp(&cond); if(*token!=';') sntx_err(SEMI_EXPECTED); prog++; temp2 = prog; brace = 1; while(brace) { get_token(); if(*token=='(') brace++; if(*token==')') brace--; } if(cond) interp_block(); else { find_eob(); return; } prog = temp2; eval_exp(&cond); prog = temp; } }
/* Find value of number, variable or function. */ void atom(int *value) { int i; switch(token_type) { case IDENTIFIER: i = internal_func(token); if(i!= -1) { /* call "standard library" function */ *value = (*intern_func[i].p)(); } else if(find_func(token)){ /* call user-defined function */ call(); *value = ret_value; } else *value = find_var(token); /* get var's value */ get_token(); return; case NUMBER: /* is numeric constant */ *value = atoi(token); get_token(); return; case DELIMITER: /* see if character constant */ if(*token=='\'') { *value = *prog; prog++; if(*prog!='\'') sntx_err(QUOTE_EXPECTED); prog++; get_token(); } return; default: if(*token==')') return; /* process empty expression */ else sntx_err(SYNTAX); /* syntax error */ } }
void finish_check() { get_token(); if(*token!=')') sntx_err(PAREN_EXPECTED); get_token(); if(*token!=';') sntx_err(SEMI_EXPECTED); putback(); }
/* Call puts(). */ int call_puts(void) { get_token(); if(*token != '(') sntx_err(PAREN_EXPECTED); get_token(); if(token_type!= STRING) sntx_err(QUOTE_EXPECTED); puts(token); get_token(); if(*token!=')') sntx_err(PAREN_EXPECTED); get_token(); if(*token!=';') sntx_err(SEMI_EXPECTED); putback(); return 0; }
/* Обработка выражения в присваивании */ void eval_exp0(int *value) { char temp[ID_LEN]; /* содержит имя переменной, которой присваивается значение */ register int temp_tok; if(token_type == IDENTIFIER) { if(is_var(token)) { /* если эта переменная, посмотреть, присваивается ли ей значение */ if(is_arr(token)) { sntx_err(SYNTAX); // todo: make message: redefinition of array is illegal } strcpy(temp, token); temp_tok = token_type; get_token(); if(*token == '=') { /* это присваивание */ get_token(); eval_exp0(value); /* вычислить присваемое значение */ assign_var(temp, *value); /* присвоить значение */ return; } else { /* не присваивание */ putback(); /* востановление лексемы */ strcpy(token, temp); token_type = temp_tok; } } else if(is_arr(token)) { strcpy(temp, token); temp_tok = token_type; get_token(); if(*token == '[') { get_token(); eval_exp0(value); // вычисление выражения в [] скобках int arr_index = *value; get_token(); // '=' or ';' if(*token == '=') { /* это присваивание */ get_token(); eval_exp0(value); /* вычислить присваемое значение */ assign_arr_element(temp, arr_index, *value); /* присвоить значение */ return; } else { /* не присваивание */ putback(); /* востановление лексемы */ strcpy(token, temp); token_type = temp_tok; } } else { sntx_err(ASSIGN_ARRAY_ILLEGAL); } } } eval_exp1(value); }
void local_push(struct variable_type i) { if(lvartos>NUM_LOCAL_VARS) sntx_err(TOO_MANY_LVARS); local_var_stack[lvartos] = i; lvartos++; }
// be careful.. it can go through recursion. // do not use AssignVar, SetVar.. and so on. // which makes to run this function again. // these functions gets argment with the CVar type... // and calls this function again. CVar::CVar(CVar &var) { value = 0; file = NULL; string = NULL; var_name = NULL; cbr = var.cbr; var_type = var.var_type; SetName(var.var_name); next = var.next; prev = var.prev; switch(var_type) { case INT : case CHAR : SetValue(var.value); break; case STRING : SetString(var.string); break; case File : SetFile(var.file); break; default : sntx_err(INTERNAL_ERROR); } }
/* Push index of local variable stack. */ void func_push(int i) { if(functos>NUM_FUNC) sntx_err(NEST_FUNC); call_stack[functos] = i; functos++; }
void CVar::SetName(char *str) { if ( var_name ) delete var_name; var_name = new char[ strlen(str)+1 ]; if ( !var_name ) sntx_err(NOT_ENOUGH_MEM); strcpy(var_name, str); }
/* Interpret a single statement or block of code. When interp_block() returns from its initial call, the final brace (or a return) in main() has been encountered. */ void interp_block(void) { int value; char block = 0; do { token_type = get_token(); /* If interpreting single statement, return on first semicolon. */ /* see what kind of token is up */ if(token_type == IDENTIFIER) { /* Not a keyword, so process expression. */ putback(); /* restore token to input stream for further processing by eval_exp() */ eval_exp(&value); /* process the expression */ if(*token!=';') sntx_err(SEMI_EXPECTED); } else if(token_type==BLOCK) { /* if block delimiter */ if(*token == '{') /* is a block */ block = 1; /* interpreting block, not statement */ else return; /* is a }, so return */ } else /* is keyword */ switch(tok) { case CHAR: case INT: /* declare local variables */ putback(); decl_local(); break; case RETURN: /* return from function call */ func_ret(); return; case IF: /* process an if statement */ exec_if(); break; case ELSE: /* process an else statement */ find_eob(); /* find end of else block and continue execution */ break; case WHILE: /* process a while loop */ exec_while(); break; case DO: /* process a do-while loop */ exec_do(); break; case FOR: /* process a for loop */ exec_for(); break; case END: exit(0); } } while (tok != FINISHED && block); }
void motors() { int lspeed, rspeed; start_check(); eval_exp(&lspeed); if ((lspeed < -100) || (lspeed > 100)) sntx_err(PARAM_ERR); get_token(); // look for comma separator if(*token != ',') sntx_err(SYNTAX); // syntax error eval_exp(&rspeed); if ((rspeed < -100) || (rspeed > 100)) sntx_err(PARAM_ERR); setPWM(lspeed, rspeed); finish_check(); }
/* Получение значения числа, переменной или функции. */ void atom(int *value) { int i; switch(token_type) { case IDENTIFIER: i = internal_func(token); if(i!= -1) { /* вызов функции из "стандартной билиотеки" */ *value = (*intern_func[i].p)(); } else if(find_func(token)) { /* вызов функции, определенной пользователем */ call(); *value = ret_value; } else if(arr_exists(token)) { *value = find_arr_element(token, *value); } else { *value = find_var(token); /* получение значения переменной */ } get_token(); return; case NUMBER: /* числовая константа */ *value = atoi(token); get_token(); return; case DELIMITER: /* это символьная константа? */ if(*token == '\'') { *value = *prog; prog++; if(*prog!='\'') { sntx_err(QUOTE_EXPECTED); } prog++; get_token(); return ; } if(*token==')') { return; /* обработка пустого выражения */ } else { sntx_err(SYNTAX); /* синтаксическая ошибка */ } default: sntx_err(SYNTAX); /* синтаксическая ошибка */ } }
/* Process parenthesized expression. */ void eval_exp5(int *value) { if((*token == '(')) { get_token(); eval_exp0(value); /* get subexpression */ if(*token != ')') sntx_err(PAREN_EXPECTED); get_token(); } else atom(value); }
void delay() { int del; start_check(); eval_exp(&del); if ((del < 0) || (del > 1000000)) sntx_err(PARAM_ERR); delayMS(del ); finish_check(); }
/* Обработка выражения в скобках. */ void eval_exp5(int *value) { if(*token == '(') { get_token(); eval_exp0(value); /* вычисление подвыражения */ if(*token != ')') { sntx_err(PAREN_EXPECTED); } get_token(); } else { atom(value); } }
/* A built-in console output function. */ int print(void) { int i; get_token(); if(*token!='(') sntx_err(PAREN_EXPECTED); get_token(); if(token_type==STRING) { /* output a string */ printf("%s ", token); } else { /* output a number */ putback(); eval_exp(&i); printf("%d ", i); } get_token(); if(*token!= ')') sntx_err(PAREN_EXPECTED); get_token(); if(*token!=';') sntx_err(SEMI_EXPECTED); putback(); return 0; }
int find_var(char *s) { int i; for(i=lvartos-1; i>=call_stack[functos-1]; i--) if(!strcmp1(local_var_stack[i].var_name, token)) return local_var_stack[i].value; for(i=0; i<NUM_GLOBAL_VARS; i++) if(!strcmp1(global_vars[i].var_name, s)) return global_vars[i].value; sntx_err(NOT_VAR); }
/* Точка входа для вычисления выражение в синтаксическом дереве */ void eval_exp(int *value) { get_token(); if(!*token) { sntx_err(NO_EXP); return; } if(*token == ';') { *value = 0; /* пустое выражение */ return; } eval_exp0(value); putback(); /* возврат последней лексемы во входной поток */ }
void CVar::AssignVar(class CVar var) { switch(var_type) { case INT : case CHAR : SetValue(var.value); break; case STRING : SetString(var.string); break; case File : SetFile(var.file); default : sntx_err(INTERNAL_ERROR); } }
void CVar::SetString(char *str) { // if memory is allocated, and not copied object, dealloc memory. if (string) delete string; string = new char[strlen(str)+1]; if (!string) { sntx_err(NOT_ENOUGH_MEM); } strcpy(string, str); }
void decl_global() { get_token(); global_vars[gvar_index].var_type = tok; global_vars[gvar_index].value = 0; do { get_token(); strcpy1(global_vars[gvar_index].var_name, token); get_token(); gvar_index++; } while(*token==','); if(*token!=';') sntx_err(SEMI_EXPECTED); }
void get_params() { struct variable_type *p; int i; i = lvartos-1; do { get_token(); p = &local_var_stack[i]; if(*token!=')') { if(tok!=INT && tok!=CHAR) sntx_err(TYPE_EXPECTED); p->var_type = token_type; get_token(); strcpy1(p->var_name, token); get_token(); i--; } else break; } while(*token==','); if(*token!=')') sntx_err(PAREN_EXPECTED); }
/* Entry point into parser. */ void eval_exp(int *value) { get_token(); if(!*token) { sntx_err(NO_EXP); return; } if(*token==';') { *value = 0; /* empty expression */ return; } eval_exp0(value); putback(); /* return last token read to input stream */ }
void decl_local() { struct variable_type i; get_token(); i.var_type = tok; i.value = 0; do { get_token(); strcpy1(i.var_name, token); local_push(i); get_token(); } while(*token==','); if(*token!=';') sntx_err(SEMI_EXPECTED); }
void eval_exp(int *value) { get_token(); if(!*token) { sntx_err(NO_EXP); return; } if(*token==';') { *value = 0; return; } eval_exp0(value); putback(); }
void atom(int *value) { int i; switch(token_type) { case IDENTIFIER: i = internal_func(token); if(i!= -1) *value = (*intern_func[i].p)(); else if(find_func(token)) { call(); *value = ret_value; } else *value = find_var(token); get_token(); return; case NUMBER: *value = atoi1(token); get_token(); return; case DELIMITER: if(*token=='\'') { *value = *prog; prog++; if(*prog!='\'') sntx_err(QUOTE_EXPECTED); prog++; get_token(); } return; default: if(*token==')') return; else sntx_err(SYNTAX); } }
void exec_do() { int cond; char *temp; putback(); temp = prog; get_token(); interp_block(); get_token(); if(tok!=WHILE) sntx_err(WHILE_EXPECTED); eval_exp(&cond); if(cond) prog = temp; }
/* Execute a do loop. */ void exec_do(void) { int cond; char *temp; putback(); temp = prog; /* save location of top of do loop */ get_token(); /* get start of loop */ interp_block(); /* interpret loop */ get_token(); if(tok != WHILE) sntx_err(WHILE_EXPECTED); eval_exp(&cond); /* check the loop condition */ if(cond) prog = temp; /* if true loop; otherwise, continue on */ }