void GCodeParser::debug() { SERIAL_ECHOPAIR("Command: ", command_ptr); SERIAL_ECHOPAIR(" (", command_letter); SERIAL_ECHO(codenum); SERIAL_ECHOLNPGM(")"); #if ENABLED(FASTER_GCODE_PARSER) SERIAL_ECHO(" args: \""); for (char c = 'A'; c <= 'Z'; ++c) if (seen(c)) { SERIAL_CHAR(c); SERIAL_CHAR(' '); } #else SERIAL_ECHOPAIR(" args: \"", command_args); #endif SERIAL_ECHOPGM("\""); if (string_arg) { SERIAL_ECHOPGM(" string: \""); SERIAL_ECHO(string_arg); SERIAL_CHAR('"'); } SERIAL_ECHOPGM("\n\n"); for (char c = 'A'; c <= 'Z'; ++c) { if (seen(c)) { SERIAL_ECHOPAIR("Code '", c); SERIAL_ECHOPGM("':"); if (has_value()) { SERIAL_ECHOPAIR("\n float: ", value_float()); SERIAL_ECHOPAIR("\n long: ", value_long()); SERIAL_ECHOPAIR("\n ulong: ", value_ulong()); SERIAL_ECHOPAIR("\n millis: ", value_millis()); SERIAL_ECHOPAIR("\n sec-ms: ", value_millis_from_seconds()); SERIAL_ECHOPAIR("\n int: ", value_int()); SERIAL_ECHOPAIR("\n ushort: ", value_ushort()); SERIAL_ECHOPAIR("\n byte: ", (int)value_byte()); SERIAL_ECHOPAIR("\n bool: ", (int)value_bool()); SERIAL_ECHOPAIR("\n linear: ", value_linear_units()); SERIAL_ECHOPAIR("\n celsius: ", value_celsius()); } else SERIAL_ECHOPGM(" (no value)"); SERIAL_ECHOPGM("\n\n"); } } }
int paramList::getInt(unsigned int const paramNumber, int const minimum, int const maximum) const { if (paramNumber >= this->paramVector.size()) throw(fault("Not enough parameters", fault::CODE_TYPE)); if (this->paramVector[paramNumber].type() != value::TYPE_INT) throw(fault("Parameter that is supposed to be integer is not", fault::CODE_TYPE)); int const intvalue(static_cast<int>( value_int(this->paramVector[paramNumber]))); if (intvalue < minimum) throw(fault("Integer parameter too low", fault::CODE_TYPE)); if (intvalue > maximum) throw(fault("Integer parameter too high", fault::CODE_TYPE)); return intvalue; }
struct value env_lookup(struct env e, char *name) { int i; struct value err = {.type = VERR, .v = 3}; for(i = e.top - 1; i >= 0; i--) { if(strcmp(name, e.tab[i].name) == 0) return e.tab[i].v; } return err; } struct value value_int(int v) { struct value x = {.type = VINT, .v = v}; return x; } struct value value_bool(bool b) { struct value x = {.type = VBOOL, .b = b}; return x; } struct value value_err(struct value v1, struct value v2, int e) { struct value x = {.type = VERR, .v = e}; if(v1.type == VERR) return v1; if(v2.type == VERR) return v2; return x; } struct sexp *atom_i(int v) { struct sexp *s = malloc(sizeof(struct sexp)); s->type = ATOM_I; s->atom_i = v; return s; } struct sexp *atom_b(bool v) { struct sexp *s = malloc(sizeof(struct sexp)); s->type = ATOM_B; s->atom_b = v; return s; } struct sexp *atom_n(char *n) { struct sexp *s = malloc(sizeof(struct sexp)); s->type = ATOM_N; strcpy(s->atom_n, n); return s; } struct sexp *sexp(enum op op, struct sexp *s1, struct sexp *s2, struct sexp *s3) { struct sexp *s = malloc(sizeof(struct sexp)); s->type = SEXP; s->sexp.op = op; s->sexp.s1 = s1; s->sexp.s2 = s2; s->sexp.s3 = s3; return s; } struct value eval(struct env env, struct sexp *s) { struct value v1, v2, v3; switch(s->type) { case ATOM_B: return value_bool(s->atom_b); case ATOM_I: return value_int(s->atom_i); case ATOM_N: return env_lookup(env, s->atom_n); default: switch(s->sexp.op) { case ADD: v1 = eval(env, s->sexp.s1); v2 = eval(env, s->sexp.s2); if(v1.type == VINT && v2.type == VINT) return value_int(v1.v + v2.v); else return value_err(v1, v2, 1); case SUB: v1 = eval(env, s->sexp.s1); v2 = eval(env, s->sexp.s2); if(v1.type == VINT && v2.type == VINT) return value_int(v1.v - v2.v); else return value_err(v1, v2, 1); case MUL: v1 = eval(env, s->sexp.s1); v2 = eval(env, s->sexp.s2); if(v1.type == VINT && v2.type == VINT) return value_int(v1.v * v2.v); else return value_err(v1, v2, 1); case DIV: v1 = eval(env, s->sexp.s1); v2 = eval(env, s->sexp.s2); if(v1.type == VINT && v2.type == VINT) if(v2.v == 0) return value_err(v1, v1, 2); else return value_int(v1.v / v2.v); else return value_err(v1, v2, 1); case LT: v1 = eval(env, s->sexp.s1); v2 = eval(env, s->sexp.s2); if(v1.type == VINT && v2.type == VINT) return value_bool(v1.v < v2.v); else return value_err(v1, v2, 1); case GT: v1 = eval(env, s->sexp.s1); v2 = eval(env, s->sexp.s2); if(v1.type == VINT && v2.type == VINT) return value_bool(v1.v > v2.v); else return value_err(v1, v2, 1); case EQ: v1 = eval(env, s->sexp.s1); v2 = eval(env, s->sexp.s2); if(v1.type == VINT && v2.type == VINT) return value_bool(v1.v == v2.v); else return value_err(v1, v2, 1); case IF: v1 = eval(env, s->sexp.s1); if(v1.type == VBOOL) if(v1.b) return eval(env, s->sexp.s2); else return eval(env, s->sexp.s3); else return value_err(v1, v1, 1); case LET: v1 = eval(env, s->sexp.s2); if (v1.type == VERR) { return v1; } return eval(env_add(env, s->sexp.s1->atom_n, eval(env, s->sexp.s2)), s->sexp.s3); } } } char line[256]; int pos; char tok[16]; void run(struct sexp *s) { struct value v = eval(env0(), s); if(v.type == VINT) printf("%d\n", v.v); else if(v.type == VBOOL) printf("%s\n", v.b ? "true" : "false"); else { if(v.v == 1) printf("Type Mismatch\n"); else if (v.v == 2) printf("Division By Zero\n"); else printf("Unbound Identifier\n"); } } void lex() { int i; tok[0] = 0; while(line[pos] == ' ') pos++; switch(line[pos]) { case '(': case ')': case '+': case '-': case '*': case '/': case '<': case '>': case '=': tok[0] = line[pos]; tok[1] = 0; pos++; return; default: i = 0; if(line[pos] >= '0' && line[pos] <= '9') { while(line[pos] >= '0' && line[pos] <= '9') tok[i++] = line[pos++]; tok[i] = 0; return; } if(line[pos] >= 'a' && line[pos] <= 'z') { while(line[pos] >= 'a' && line[pos] <= 'z') tok[i++] = line[pos++]; tok[i] = 0; return; } } }
int xml_walker_t::value_int(int def,const char* key) { if(has_key(key)) return value_int(key); return def; }