uint8_t verificar_funciones(uint8_t * cadena, FILE * archivo_output) { uint16_t len = strlen(cadena); uint8_t temp[len+1]; memset(temp, 0, sizeof(temp)); uint16_t i = 0; uint8_t chars = 0; uint8_t espacios = 0; uint16_t indice = 0; for(i=1;i<len;i++) { if(isspace(cadena[i])) { if(chars == 1 && espacios == 0) espacios++; } else { if(chars == 0) chars++; else if(chars == 1 && espacios == 1) { if(strcmp(temp, "raw_input") == 0 || strcmp(temp, "list") == 0) { debug("\nError: la definicion de funciones no debe llevar variables\n", linea); return 0; } else return 1; } temp[indice++] = cadena[i]; } } uint8_t id = 0; if(strcmp(temp, "raw_input") == 0) { id = var_get(temp); if(id != 0) { debug("\nAviso en liea %d: has repetido la declaracion #raw_input mas de una vez, por lo cual se ha omitido. No causa conflictos, pero se recomienda que se elimine\n", linea); } else { id = var_put(temp, RAW_INPUT); if(id == 0 || id == 2) return 0; fprintf(archivo_output, "#include \"include/raw_input.h\"\n"); } } else if(strcmp(temp, "list") == 0) { id = var_get(temp); if(id != 0) debug("\nAviso en linea %d: has repetido la declaracion #list mas de una vez, por lo cual se ha omitido. No causa conflictos, pero se recomienda que se elimine\n", linea); else { id = var_put(temp, LIST); if(id == 0 || id == 2) return 0; fprintf(archivo_output, "#include \"include/list.h\"\n"); list_existe++; } } return 1; }
uint8_t comentario_parser(uint8_t * cadena, uint16_t index, uint8_t token_t) { index++; uint16_t len = strlen(cadena); uint8_t temp[len+1]; memset(temp, 0, sizeof(temp)); uint16_t i=0; uint16_t indice = 0; uint8_t chars = 0; uint8_t espacios = 0; for(i=index;i<len;i++) { if(isspace(cadena[i])) { if(chars == 1 && espacios == 0) espacios++; } else if(!isalpha(cadena[i]) && !isdigit(cadena[i]) && cadena[i] != '_') { debug("\nError en linea %d: el compilador encontro un intento de definir una variable en un comentario. Sin embargo, el valor %c no es permitido\n", linea,cadena[i]); return 0; } else { if(chars == 0 && espacios == 0) chars++; else if(espacios == 1) { debug("\nError en linea %d: el compilador encontro un intento de definir una variable en un comentario. Sin embargo, el nombre de la variable no debe contener espacios\n", linea); return 0; } temp[indice++] = cadena[i]; } } if(!check_keyword(temp)) return 0; else if(indice == 0) { debug("\nError en linea %d: debes ingresar el nombre de una variable\n", linea); return 0; } uint8_t token = ht_get(temp); if(token != 0) { if(token == NUMERO && token_t == CHAR) debug("\nError en linea %d: la variable \"%s\" ya fue declarada como entero. Por lo tanto, no puedes declarla como \"char\"\n",linea,temp); else if((token == CADENA || token == FLOAT) && token_t == CHAR) debug("\nError en linea %d: la variable \"%s\" ya fue declarada. No puedes redefinirla como \"char\"\n",linea,temp); else if(token == NUMERO && token_t == FLOAT) debug("\nError en linea %d: la variable \"%s\" ya fue declarada como entero. Por lo tanto, no puedes redefinirla como \"float\"",linea,temp); else if(token == FLOAT && token_t == FLOAT) debug("\nError en linea %d: la variable \"%s\" ya fue declarada. No puedes redefinirla como \"float\"\n",linea,temp); return 0; } else if(token == 0) { if(var_get(temp) != 0) debug("\nAviso en la linea %d: has repetido la misma declaracion, por lo cual se ha omitido. No causa conflictos, pero se recomienda que se elimine\n", linea); else { uint8_t id = var_put(temp, token_t); if(id == 0 || id == 2) return 0; } } return 1; }
static char * exec_instr( pInstr s ) { pCell tc, tc2; char buffer[16]; switch (s->opcode) { case SET: /* operand must be a string */ tc = temp_pop(); switch (tc->type) { case mu: fprintf(stderr, "exec_inst/SET: warning - unhandled case mu\n" ); break; case string_t: var_put(s->operand.contents.s, tc->contents.s); break; case int_t: var_put_int(s->operand.contents.s, tc->contents.i); break; } break; case EMIT: tc = temp_pop(); switch (tc->type) { case mu: fprintf(stderr, "exec_inst/EMIT: warning - unhandled case mu\n" ); break; case string_t: return tc->contents.s; case int_t: sprintf(buffer, "%i", tc->contents.i); return strdup(buffer); } case PUSHV: { struct var *v = var_lookup(vars, s->operand.contents.s); if (v == 0) { fprintf(stderr, "attempted to use unknown variable \"%s\" in expression.\n", s->operand.contents.s); push_str("(NULL)"); } else { switch (v->type) { case mu: fprintf(stderr, "exec_inst/PUSHV: warning - unhandled case mu\n" ); break; case string_t: push_str(strdup(v->value.s)); break; case int_t: push_int(v->value.i); break; } } } break; case INVOKE: { pRule r = rule_find(rule_base, s->operand.contents.s); if (r) { push_str(resolve_rule(rule_base, r)); } else { fprintf(stderr, "attempted to invoke non-existent rule \"%s\" in expression.\n", s->operand.contents.s); push_str(NULL); } } break; case PUSH: switch (s->operand.type) { case mu: fprintf(stderr, "exec_inst/PUSH: warning - unhandled case mu\n" ); break; case string_t: push_str(strdup(s->operand.contents.s)); break; case int_t: push_int(s->operand.contents.i); break; } break; case ADD: tc = temp_pop(); tc2 = temp_pop(); if ((tc->type == int_t) && (tc2->type == int_t)) { push_int(tc->contents.i + tc2->contents.i); } else { char *s0, *s1; /* string concatenation */ s0 = ((tc->type == int_t) ? itoa(tc->contents.i) : (tc->contents.s)); s1 = ((tc2->type == int_t) ? itoa(tc2->contents.i) : (tc2->contents.s)); push_str(concat(s1, s0)); free(s0); free(s1); } break; case SUB: tc = temp_pop(); tc2 = temp_pop(); if ((tc->type == int_t) && (tc2->type == int_t)) { push_int(tc2->contents.i + tc->contents.i); } break; case MUL: tc = temp_pop(); tc2 = temp_pop(); if ((tc->type == int_t) && (tc2->type == int_t)) { push_int(tc->contents.i * tc2->contents.i); } break; case DIV: tc = temp_pop(); tc2 = temp_pop(); if ((tc->type == int_t) && (tc2->type == int_t)) { push_int(tc2->contents.i / tc->contents.i); } break; case MOD: tc = temp_pop(); tc2 = temp_pop(); if ((tc->type == int_t) && (tc2->type == int_t)) { push_int(tc2->contents.i % tc->contents.i); } break; case RANDOM: tc2 = temp_pop(); tc = temp_pop(); if ((tc->type == int_t) && (tc2->type == int_t)) { push_int((ranq1() % (tc2->contents.i - tc->contents.i + 1)) + tc->contents.i); } break; case LESSER: tc2 = temp_pop(); tc = temp_pop(); if ((tc->type == int_t) && (tc2->type == int_t)) { push_int(min(tc->contents.i, tc2->contents.i)); } break; case GREATER: tc2 = temp_pop(); tc = temp_pop(); if ((tc->type == int_t) && (tc2->type == int_t)) { push_int(max(tc->contents.i, tc2->contents.i)); } break; } return NULL; }