bc: reduce indentation, no code changes
No binary (build failed)
—
(log yok)
| @@ -3090,184 +3090,184 @@ static BC_STATUS zbc_lex_token(void) | |
| // This is the workhorse of the lexer. | |
| switch (c) { | |
| - | // case '\0': // probably never reached |
| - | // p->lex_inbuf--; |
| - | // p->lex = XC_LEX_EOF; |
| - | // break; |
| - | case '\n': |
| - | p->lex_line++; |
| - | p->lex = XC_LEX_NLINE; |
| - | break; |
| - | case '\t': |
| - | case '\v': |
| - | case '\f': |
| - | case '\r': |
| - | case ' ': |
| - | bc_lex_whitespace(); |
| - | break; |
| - | case '!': |
| - | parse_lex_by_checking_eq_sign(XC_LEX_OP_REL_NE, BC_LEX_OP_BOOL_NOT); |
| - | if (p->lex == BC_LEX_OP_BOOL_NOT) { |
| - | s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("!"); |
| - | if (s) RETURN_STATUS(s); |
| - | } |
| - | break; |
| - | case '"': |
| - | s = zbc_lex_string(); |
| - | break; |
| - | case '#': |
| - | s = zbc_POSIX_does_not_allow("'#' script comments"); |
| + | // case '\0': // probably never reached |
| + | // p->lex_inbuf--; |
| + | // p->lex = XC_LEX_EOF; |
| + | // break; |
| + | case '\n': |
| + | p->lex_line++; |
| + | p->lex = XC_LEX_NLINE; |
| + | break; |
| + | case '\t': |
| + | case '\v': |
| + | case '\f': |
| + | case '\r': |
| + | case ' ': |
| + | bc_lex_whitespace(); |
| + | break; |
| + | case '!': |
| + | parse_lex_by_checking_eq_sign(XC_LEX_OP_REL_NE, BC_LEX_OP_BOOL_NOT); |
| + | if (p->lex == BC_LEX_OP_BOOL_NOT) { |
| + | s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("!"); |
| if (s) RETURN_STATUS(s); | |
| - | bc_lex_lineComment(); |
| - | break; |
| - | case '%': |
| - | parse_lex_by_checking_eq_sign(BC_LEX_OP_ASSIGN_MODULUS, XC_LEX_OP_MODULUS); |
| - | break; |
| - | case '&': |
| - | c2 = *p->lex_inbuf; |
| - | if (c2 == '&') { |
| - | s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("&&"); |
| - | if (s) RETURN_STATUS(s); |
| - | p->lex_inbuf++; |
| - | p->lex = BC_LEX_OP_BOOL_AND; |
| - | } else { |
| - | p->lex = XC_LEX_INVALID; |
| - | s = bc_error_bad_character('&'); |
| - | } |
| - | break; |
| - | case '(': |
| - | case ')': |
| - | p->lex = (BcLexType)(c - '(' + BC_LEX_LPAREN); |
| - | break; |
| - | case '*': |
| - | parse_lex_by_checking_eq_sign(BC_LEX_OP_ASSIGN_MULTIPLY, XC_LEX_OP_MULTIPLY); |
| - | break; |
| - | case '+': |
| - | c2 = *p->lex_inbuf; |
| - | if (c2 == '+') { |
| - | p->lex_inbuf++; |
| - | p->lex = BC_LEX_OP_INC; |
| - | } else |
| - | parse_lex_by_checking_eq_sign(BC_LEX_OP_ASSIGN_PLUS, XC_LEX_OP_PLUS); |
| - | break; |
| - | case ',': |
| - | p->lex = BC_LEX_COMMA; |
| - | break; |
| - | case '-': |
| - | c2 = *p->lex_inbuf; |
| - | if (c2 == '-') { |
| - | p->lex_inbuf++; |
| - | p->lex = BC_LEX_OP_DEC; |
| - | } else |
| - | parse_lex_by_checking_eq_sign(BC_LEX_OP_ASSIGN_MINUS, XC_LEX_OP_MINUS); |
| - | break; |
| - | case '.': |
| - | if (isdigit(*p->lex_inbuf)) |
| - | s = zbc_lex_number(c); |
| - | else { |
| - | p->lex = BC_LEX_KEY_LAST; |
| - | s = zbc_POSIX_does_not_allow("'.' as 'last'"); |
| - | } |
| - | break; |
| - | case '/': |
| - | c2 = *p->lex_inbuf; |
| - | if (c2 == '*') |
| - | s = zbc_lex_comment(); |
| - | else |
| - | parse_lex_by_checking_eq_sign(BC_LEX_OP_ASSIGN_DIVIDE, XC_LEX_OP_DIVIDE); |
| - | break; |
| - | case '0': |
| - | case '1': |
| - | case '2': |
| - | case '3': |
| - | case '4': |
| - | case '5': |
| - | case '6': |
| - | case '7': |
| - | case '8': |
| - | case '9': |
| - | case 'A': |
| - | case 'B': |
| - | case 'C': |
| - | case 'D': |
| - | case 'E': |
| - | case 'F': |
| + | } |
| + | break; |
| + | case '"': |
| + | s = zbc_lex_string(); |
| + | break; |
| + | case '#': |
| + | s = zbc_POSIX_does_not_allow("'#' script comments"); |
| + | if (s) RETURN_STATUS(s); |
| + | bc_lex_lineComment(); |
| + | break; |
| + | case '%': |
| + | parse_lex_by_checking_eq_sign(BC_LEX_OP_ASSIGN_MODULUS, XC_LEX_OP_MODULUS); |
| + | break; |
| + | case '&': |
| + | c2 = *p->lex_inbuf; |
| + | if (c2 == '&') { |
| + | s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("&&"); |
| + | if (s) RETURN_STATUS(s); |
| + | p->lex_inbuf++; |
| + | p->lex = BC_LEX_OP_BOOL_AND; |
| + | } else { |
| + | p->lex = XC_LEX_INVALID; |
| + | s = bc_error_bad_character('&'); |
| + | } |
| + | break; |
| + | case '(': |
| + | case ')': |
| + | p->lex = (BcLexType)(c - '(' + BC_LEX_LPAREN); |
| + | break; |
| + | case '*': |
| + | parse_lex_by_checking_eq_sign(BC_LEX_OP_ASSIGN_MULTIPLY, XC_LEX_OP_MULTIPLY); |
| + | break; |
| + | case '+': |
| + | c2 = *p->lex_inbuf; |
| + | if (c2 == '+') { |
| + | p->lex_inbuf++; |
| + | p->lex = BC_LEX_OP_INC; |
| + | } else |
| + | parse_lex_by_checking_eq_sign(BC_LEX_OP_ASSIGN_PLUS, XC_LEX_OP_PLUS); |
| + | break; |
| + | case ',': |
| + | p->lex = BC_LEX_COMMA; |
| + | break; |
| + | case '-': |
| + | c2 = *p->lex_inbuf; |
| + | if (c2 == '-') { |
| + | p->lex_inbuf++; |
| + | p->lex = BC_LEX_OP_DEC; |
| + | } else |
| + | parse_lex_by_checking_eq_sign(BC_LEX_OP_ASSIGN_MINUS, XC_LEX_OP_MINUS); |
| + | break; |
| + | case '.': |
| + | if (isdigit(*p->lex_inbuf)) |
| s = zbc_lex_number(c); | |
| - | break; |
| - | case ';': |
| - | p->lex = BC_LEX_SCOLON; |
| - | break; |
| - | case '<': |
| - | parse_lex_by_checking_eq_sign(XC_LEX_OP_REL_LE, XC_LEX_OP_REL_LT); |
| - | break; |
| - | case '=': |
| - | parse_lex_by_checking_eq_sign(XC_LEX_OP_REL_EQ, BC_LEX_OP_ASSIGN); |
| - | break; |
| - | case '>': |
| - | parse_lex_by_checking_eq_sign(XC_LEX_OP_REL_GE, XC_LEX_OP_REL_GT); |
| - | break; |
| - | case '[': |
| - | case ']': |
| - | p->lex = (BcLexType)(c - '[' + BC_LEX_LBRACKET); |
| - | break; |
| - | case '\\': |
| - | if (*p->lex_inbuf == '\n') { |
| - | p->lex = XC_LEX_WHITESPACE; |
| - | p->lex_inbuf++; |
| - | } else |
| - | s = bc_error_bad_character(c); |
| - | break; |
| - | case '^': |
| - | parse_lex_by_checking_eq_sign(BC_LEX_OP_ASSIGN_POWER, XC_LEX_OP_POWER); |
| - | break; |
| - | case 'a': |
| - | case 'b': |
| - | case 'c': |
| - | case 'd': |
| - | case 'e': |
| - | case 'f': |
| - | case 'g': |
| - | case 'h': |
| - | case 'i': |
| - | case 'j': |
| - | case 'k': |
| - | case 'l': |
| - | case 'm': |
| - | case 'n': |
| - | case 'o': |
| - | case 'p': |
| - | case 'q': |
| - | case 'r': |
| - | case 's': |
| - | case 't': |
| - | case 'u': |
| - | case 'v': |
| - | case 'w': |
| - | case 'x': |
| - | case 'y': |
| - | case 'z': |
| - | s = zbc_lex_identifier(); |
| - | break; |
| - | case '{': |
| - | case '}': |
| - | p->lex = (BcLexType)(c - '{' + BC_LEX_LBRACE); |
| - | break; |
| - | case '|': |
| - | c2 = *p->lex_inbuf; |
| - | if (c2 == '|') { |
| - | s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("||"); |
| - | if (s) RETURN_STATUS(s); |
| - | p->lex_inbuf++; |
| - | p->lex = BC_LEX_OP_BOOL_OR; |
| - | } else { |
| - | p->lex = XC_LEX_INVALID; |
| - | s = bc_error_bad_character(c); |
| - | } |
| - | break; |
| - | default: |
| + | else { |
| + | p->lex = BC_LEX_KEY_LAST; |
| + | s = zbc_POSIX_does_not_allow("'.' as 'last'"); |
| + | } |
| + | break; |
| + | case '/': |
| + | c2 = *p->lex_inbuf; |
| + | if (c2 == '*') |
| + | s = zbc_lex_comment(); |
| + | else |
| + | parse_lex_by_checking_eq_sign(BC_LEX_OP_ASSIGN_DIVIDE, XC_LEX_OP_DIVIDE); |
| + | break; |
| + | case '0': |
| + | case '1': |
| + | case '2': |
| + | case '3': |
| + | case '4': |
| + | case '5': |
| + | case '6': |
| + | case '7': |
| + | case '8': |
| + | case '9': |
| + | case 'A': |
| + | case 'B': |
| + | case 'C': |
| + | case 'D': |
| + | case 'E': |
| + | case 'F': |
| + | s = zbc_lex_number(c); |
| + | break; |
| + | case ';': |
| + | p->lex = BC_LEX_SCOLON; |
| + | break; |
| + | case '<': |
| + | parse_lex_by_checking_eq_sign(XC_LEX_OP_REL_LE, XC_LEX_OP_REL_LT); |
| + | break; |
| + | case '=': |
| + | parse_lex_by_checking_eq_sign(XC_LEX_OP_REL_EQ, BC_LEX_OP_ASSIGN); |
| + | break; |
| + | case '>': |
| + | parse_lex_by_checking_eq_sign(XC_LEX_OP_REL_GE, XC_LEX_OP_REL_GT); |
| + | break; |
| + | case '[': |
| + | case ']': |
| + | p->lex = (BcLexType)(c - '[' + BC_LEX_LBRACKET); |
| + | break; |
| + | case '\\': |
| + | if (*p->lex_inbuf == '\n') { |
| + | p->lex = XC_LEX_WHITESPACE; |
| + | p->lex_inbuf++; |
| + | } else |
| + | s = bc_error_bad_character(c); |
| + | break; |
| + | case '^': |
| + | parse_lex_by_checking_eq_sign(BC_LEX_OP_ASSIGN_POWER, XC_LEX_OP_POWER); |
| + | break; |
| + | case 'a': |
| + | case 'b': |
| + | case 'c': |
| + | case 'd': |
| + | case 'e': |
| + | case 'f': |
| + | case 'g': |
| + | case 'h': |
| + | case 'i': |
| + | case 'j': |
| + | case 'k': |
| + | case 'l': |
| + | case 'm': |
| + | case 'n': |
| + | case 'o': |
| + | case 'p': |
| + | case 'q': |
| + | case 'r': |
| + | case 's': |
| + | case 't': |
| + | case 'u': |
| + | case 'v': |
| + | case 'w': |
| + | case 'x': |
| + | case 'y': |
| + | case 'z': |
| + | s = zbc_lex_identifier(); |
| + | break; |
| + | case '{': |
| + | case '}': |
| + | p->lex = (BcLexType)(c - '{' + BC_LEX_LBRACE); |
| + | break; |
| + | case '|': |
| + | c2 = *p->lex_inbuf; |
| + | if (c2 == '|') { |
| + | s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("||"); |
| + | if (s) RETURN_STATUS(s); |
| + | p->lex_inbuf++; |
| + | p->lex = BC_LEX_OP_BOOL_OR; |
| + | } else { |
| p->lex = XC_LEX_INVALID; | |
| s = bc_error_bad_character(c); | |
| - | break; |
| + | } |
| + | break; |
| + | default: |
| + | p->lex = XC_LEX_INVALID; |
| + | s = bc_error_bad_character(c); |
| + | break; |
| } | |
| RETURN_STATUS(s); | |
| @@ -3357,74 +3357,74 @@ static BC_STATUS zdc_lex_token(void) | |
| // This is the workhorse of the lexer. | |
| switch (c) { | |
| - | // case '\0': // probably never reached |
| - | // p->lex = XC_LEX_EOF; |
| - | // break; |
| - | case '\n': |
| - | // '\n' is XC_LEX_NLINE, not XC_LEX_WHITESPACE |
| - | // (and "case '\n':" is not just empty here) |
| - | // only to allow interactive dc have a way to exit |
| - | // "parse" stage of "parse,execute" loop |
| - | // on <enter>, not on _next_ token (which would mean |
| - | // commands are not executed on pressing <enter>). |
| - | // IOW: typing "1p<enter>" should print "1" _at once_, |
| - | // not after some more input. |
| - | p->lex_line++; |
| - | p->lex = XC_LEX_NLINE; |
| - | break; |
| - | case '\t': |
| - | case '\v': |
| - | case '\f': |
| - | case '\r': |
| - | case ' ': |
| - | bc_lex_whitespace(); |
| - | break; |
| - | case '!': |
| - | c2 = *p->lex_inbuf; |
| - | if (c2 == '=') |
| - | p->lex = XC_LEX_OP_REL_NE; |
| - | else if (c2 == '<') |
| - | p->lex = XC_LEX_OP_REL_LE; |
| - | else if (c2 == '>') |
| - | p->lex = XC_LEX_OP_REL_GE; |
| - | else |
| - | RETURN_STATUS(bc_error_bad_character(c)); |
| - | p->lex_inbuf++; |
| - | break; |
| - | case '#': |
| - | bc_lex_lineComment(); |
| - | break; |
| - | case '.': |
| - | if (isdigit(*p->lex_inbuf)) |
| - | s = zbc_lex_number(c); |
| - | else |
| - | s = bc_error_bad_character(c); |
| - | break; |
| - | case '0': |
| - | case '1': |
| - | case '2': |
| - | case '3': |
| - | case '4': |
| - | case '5': |
| - | case '6': |
| - | case '7': |
| - | case '8': |
| - | case '9': |
| - | case 'A': |
| - | case 'B': |
| - | case 'C': |
| - | case 'D': |
| - | case 'E': |
| - | case 'F': |
| + | // case '\0': // probably never reached |
| + | // p->lex = XC_LEX_EOF; |
| + | // break; |
| + | case '\n': |
| + | // '\n' is XC_LEX_NLINE, not XC_LEX_WHITESPACE |
| + | // (and "case '\n':" is not just empty here) |
| + | // only to allow interactive dc have a way to exit |
| + | // "parse" stage of "parse,execute" loop |
| + | // on <enter>, not on _next_ token (which would mean |
| + | // commands are not executed on pressing <enter>). |
| + | // IOW: typing "1p<enter>" should print "1" _at once_, |
| + | // not after some more input. |
| + | p->lex_line++; |
| + | p->lex = XC_LEX_NLINE; |
| + | break; |
| + | case '\t': |
| + | case '\v': |
| + | case '\f': |
| + | case '\r': |
| + | case ' ': |
| + | bc_lex_whitespace(); |
| + | break; |
| + | case '!': |
| + | c2 = *p->lex_inbuf; |
| + | if (c2 == '=') |
| + | p->lex = XC_LEX_OP_REL_NE; |
| + | else if (c2 == '<') |
| + | p->lex = XC_LEX_OP_REL_LE; |
| + | else if (c2 == '>') |
| + | p->lex = XC_LEX_OP_REL_GE; |
| + | else |
| + | RETURN_STATUS(bc_error_bad_character(c)); |
| + | p->lex_inbuf++; |
| + | break; |
| + | case '#': |
| + | bc_lex_lineComment(); |
| + | break; |
| + | case '.': |
| + | if (isdigit(*p->lex_inbuf)) |
| s = zbc_lex_number(c); | |
| - | break; |
| - | case '[': |
| - | s = zdc_lex_string(); |
| - | break; |
| - | default: |
| - | p->lex = XC_LEX_INVALID; |
| + | else |
| s = bc_error_bad_character(c); | |
| - | break; |
| + | break; |
| + | case '0': |
| + | case '1': |
| + | case '2': |
| + | case '3': |
| + | case '4': |
| + | case '5': |
| + | case '6': |
| + | case '7': |
| + | case '8': |
| + | case '9': |
| + | case 'A': |
| + | case 'B': |
| + | case 'C': |
| + | case 'D': |
| + | case 'E': |
| + | case 'F': |
| + | s = zbc_lex_number(c); |
| + | break; |
| + | case '[': |
| + | s = zdc_lex_string(); |
| + | break; |
| + | default: |
| + | p->lex = XC_LEX_INVALID; |
| + | s = bc_error_bad_character(c); |
| + | break; |
| } | |
| RETURN_STATUS(s); | |
| @@ -3559,10 +3559,9 @@ static void bc_parse_reset(void) | |
| static void bc_parse_free(void) | |
| { | |
| - | IF_BC(BcParse *p = &G.prs;) |
| - | IF_BC(bc_vec_free(&p->exits);) |
| - | IF_BC(bc_vec_free(&p->conds);) |
| - | IF_BC(bc_vec_free(&p->ops);) |
| + | IF_BC(bc_vec_free(&G.prs.exits);) |
| + | IF_BC(bc_vec_free(&G.prs.conds);) |
| + | IF_BC(bc_vec_free(&G.prs.ops);) |
| bc_vec_free(&G.prs.lex_strnumbuf); | |
| } | |
| @@ -3571,7 +3570,7 @@ static void bc_parse_create(size_t fidx) | |
| BcParse *p = &G.prs; | |
| memset(p, 0, sizeof(BcParse)); | |
| - | bc_char_vec_init(&G.prs.lex_strnumbuf); |
| + | bc_char_vec_init(&p->lex_strnumbuf); |
| IF_BC(bc_vec_init(&p->exits, sizeof(size_t), NULL);) | |
| IF_BC(bc_vec_init(&p->conds, sizeof(size_t), NULL);) | |
| IF_BC(bc_vec_init(&p->ops, sizeof(BcLexType), NULL);) | |
| @@ -3938,26 +3937,26 @@ static BC_STATUS zbc_parse_incdec(BcInst *prev, bool *paren_expr, | |
| *nexprs = *nexprs + 1; | |
| switch (type) { | |
| - | case XC_LEX_NAME: |
| - | s = zbc_parse_name(prev, flags | BC_PARSE_NOCALL); |
| - | break; |
| - | case BC_LEX_KEY_IBASE: |
| - | case BC_LEX_KEY_LAST: |
| - | case BC_LEX_KEY_OBASE: |
| - | bc_parse_push(type - BC_LEX_KEY_IBASE + XC_INST_IBASE); |
| - | s = zbc_lex_next(); |
| - | break; |
| - | case BC_LEX_KEY_SCALE: |
| - | s = zbc_lex_next(); |
| - | if (s) RETURN_STATUS(s); |
| - | if (p->lex == BC_LEX_LPAREN) |
| - | s = bc_error_bad_token(); |
| - | else |
| - | bc_parse_push(XC_INST_SCALE); |
| - | break; |
| - | default: |
| + | case XC_LEX_NAME: |
| + | s = zbc_parse_name(prev, flags | BC_PARSE_NOCALL); |
| + | break; |
| + | case BC_LEX_KEY_IBASE: |
| + | case BC_LEX_KEY_LAST: |
| + | case BC_LEX_KEY_OBASE: |
| + | bc_parse_push(type - BC_LEX_KEY_IBASE + XC_INST_IBASE); |
| + | s = zbc_lex_next(); |
| + | break; |
| + | case BC_LEX_KEY_SCALE: |
| + | s = zbc_lex_next(); |
| + | if (s) RETURN_STATUS(s); |
| + | if (p->lex == BC_LEX_LPAREN) |
| s = bc_error_bad_token(); | |
| - | break; |
| + | else |
| + | bc_parse_push(XC_INST_SCALE); |
| + | break; |
| + | default: |
| + | s = bc_error_bad_token(); |
| + | break; |
| } | |
| if (!s) bc_parse_push(inst); | |
| @@ -4489,74 +4488,74 @@ static BC_STATUS zbc_parse_stmt_possibly_auto(bool auto_allowed) | |
| dbg_lex("%s:%d p->lex:%d", __func__, __LINE__, p->lex); | |
| switch (p->lex) { | |
| - | case XC_LEX_OP_MINUS: |
| - | case BC_LEX_OP_INC: |
| - | case BC_LEX_OP_DEC: |
| - | case BC_LEX_OP_BOOL_NOT: |
| - | case BC_LEX_LPAREN: |
| - | case XC_LEX_NAME: |
| - | case XC_LEX_NUMBER: |
| - | case BC_LEX_KEY_IBASE: |
| - | case BC_LEX_KEY_LAST: |
| - | case BC_LEX_KEY_LENGTH: |
| - | case BC_LEX_KEY_OBASE: |
| - | case BC_LEX_KEY_READ: |
| - | case BC_LEX_KEY_SCALE: |
| - | case BC_LEX_KEY_SQRT: |
| - | s = zbc_parse_expr(BC_PARSE_PRINT); |
| - | break; |
| - | case XC_LEX_STR: |
| - | s = zbc_parse_pushSTR(); |
| - | bc_parse_push(XC_INST_PRINT_STR); |
| - | break; |
| - | case BC_LEX_KEY_BREAK: |
| - | case BC_LEX_KEY_CONTINUE: |
| - | s = zbc_parse_break_or_continue(p->lex); |
| - | break; |
| - | case BC_LEX_KEY_FOR: |
| - | s = zbc_parse_for(); |
| - | break; |
| - | case BC_LEX_KEY_HALT: |
| - | bc_parse_push(BC_INST_HALT); |
| - | s = zbc_lex_next(); |
| - | break; |
| - | case BC_LEX_KEY_IF: |
| - | s = zbc_parse_if(); |
| - | break; |
| - | case BC_LEX_KEY_LIMITS: |
| - | // "limits" is a compile-time command, |
| - | // the output is produced at _parse time_. |
| - | printf( |
| - | "BC_BASE_MAX = "BC_MAX_OBASE_STR "\n" |
| - | "BC_DIM_MAX = "BC_MAX_DIM_STR "\n" |
| - | "BC_SCALE_MAX = "BC_MAX_SCALE_STR "\n" |
| - | "BC_STRING_MAX = "BC_MAX_STRING_STR"\n" |
| - | "BC_NAME_MAX = "BC_MAX_NAME_STR "\n" |
| - | "BC_NUM_MAX = "BC_MAX_NUM_STR "\n" |
| - | "MAX Exponent = "BC_MAX_EXP_STR "\n" |
| - | "Number of vars = "BC_MAX_VARS_STR "\n" |
| - | ); |
| - | s = zbc_lex_next(); |
| - | break; |
| - | case BC_LEX_KEY_PRINT: |
| - | s = zbc_parse_print(); |
| - | break; |
| - | case BC_LEX_KEY_QUIT: |
| - | // "quit" is a compile-time command. For example, |
| - | // "if (0 == 1) quit" terminates when parsing the statement, |
| - | // not when it is executed |
| - | QUIT_OR_RETURN_TO_MAIN; |
| - | case BC_LEX_KEY_RETURN: |
| - | if (!p->in_funcdef) |
| - | RETURN_STATUS(bc_error("'return' not in a function")); |
| - | s = zbc_parse_return(); |
| - | break; |
| - | case BC_LEX_KEY_WHILE: |
| - | s = zbc_parse_while(); |
| - | break; |
| - | default: |
| - | s = bc_error_bad_token(); |
| - | break; |
| + | case XC_LEX_OP_MINUS: |
| + | case BC_LEX_OP_INC: |
| + | case BC_LEX_OP_DEC: |
| + | case BC_LEX_OP_BOOL_NOT: |
| + | case BC_LEX_LPAREN: |
| + | case XC_LEX_NAME: |
| + | case XC_LEX_NUMBER: |
| + | case BC_LEX_KEY_IBASE: |
| + | case BC_LEX_KEY_LAST: |
| + | case BC_LEX_KEY_LENGTH: |
| + | case BC_LEX_KEY_OBASE: |
| + | case BC_LEX_KEY_READ: |
| + | case BC_LEX_KEY_SCALE: |
| + | case BC_LEX_KEY_SQRT: |
| + | s = zbc_parse_expr(BC_PARSE_PRINT); |
| + | break; |
| + | case XC_LEX_STR: |
| + | s = zbc_parse_pushSTR(); |
| + | bc_parse_push(XC_INST_PRINT_STR); |
| + | break; |
| + | case BC_LEX_KEY_BREAK: |
| + | case BC_LEX_KEY_CONTINUE: |
| + | s = zbc_parse_break_or_continue(p->lex); |
| + | break; |
| + | case BC_LEX_KEY_FOR: |
| + | s = zbc_parse_for(); |
| + | break; |
| + | case BC_LEX_KEY_HALT: |
| + | bc_parse_push(BC_INST_HALT); |
| + | s = zbc_lex_next(); |
| + | break; |
| + | case BC_LEX_KEY_IF: |
| + | s = zbc_parse_if(); |
| + | break; |
| + | case BC_LEX_KEY_LIMITS: |
| + | // "limits" is a compile-time command, |
| + | // the output is produced at _parse time_. |
| + | printf( |
| + | "BC_BASE_MAX = "BC_MAX_OBASE_STR "\n" |
| + | "BC_DIM_MAX = "BC_MAX_DIM_STR "\n" |
| + | "BC_SCALE_MAX = "BC_MAX_SCALE_STR "\n" |
| + | "BC_STRING_MAX = "BC_MAX_STRING_STR"\n" |
| + | "BC_NAME_MAX = "BC_MAX_NAME_STR "\n" |
| + | "BC_NUM_MAX = "BC_MAX_NUM_STR "\n" |
| + | "MAX Exponent = "BC_MAX_EXP_STR "\n" |
| + | "Number of vars = "BC_MAX_VARS_STR "\n" |
| + | ); |
| + | s = zbc_lex_next(); |
| + | break; |
| + | case BC_LEX_KEY_PRINT: |
| + | s = zbc_parse_print(); |
| + | break; |
| + | case BC_LEX_KEY_QUIT: |
| + | // "quit" is a compile-time command. For example, |
| + | // "if (0 == 1) quit" terminates when parsing the statement, |
| + | // not when it is executed |
| + | QUIT_OR_RETURN_TO_MAIN; |
| + | case BC_LEX_KEY_RETURN: |
| + | if (!p->in_funcdef) |
| + | RETURN_STATUS(bc_error("'return' not in a function")); |
| + | s = zbc_parse_return(); |
| + | break; |
| + | case BC_LEX_KEY_WHILE: |
| + | s = zbc_parse_while(); |
| + | break; |
| + | default: |
| + | s = bc_error_bad_token(); |
| + | break; |
| } | |
| dbg_lex_done("%s:%d done", __func__, __LINE__); | |
| @@ -4612,162 +4611,162 @@ static BcStatus bc_parse_expr_empty_ok(uint8_t flags) | |
| get_token = false; | |
| s = BC_STATUS_SUCCESS; | |
| switch (t) { | |
| - | case BC_LEX_OP_INC: |
| - | case BC_LEX_OP_DEC: |
| - | dbg_lex("%s:%d LEX_OP_INC/DEC", __func__, __LINE__); |
| - | s = zbc_parse_incdec(&prev, &paren_expr, &nexprs, flags); |
| - | rprn = bin_last = false; |
| - | //get_token = false; - already is |
| - | break; |
| - | case XC_LEX_OP_MINUS: |
| - | dbg_lex("%s:%d LEX_OP_MINUS", __func__, __LINE__); |
| - | s = zbc_parse_minus(&prev, ops_bgn, rprn, &nexprs); |
| - | rprn = false; |
| - | //get_token = false; - already is |
| - | bin_last = (prev == XC_INST_MINUS); |
| - | break; |
| - | case BC_LEX_OP_ASSIGN_POWER: |
| - | case BC_LEX_OP_ASSIGN_MULTIPLY: |
| - | case BC_LEX_OP_ASSIGN_DIVIDE: |
| - | case BC_LEX_OP_ASSIGN_MODULUS: |
| - | case BC_LEX_OP_ASSIGN_PLUS: |
| - | case BC_LEX_OP_ASSIGN_MINUS: |
| - | case BC_LEX_OP_ASSIGN: |
| - | dbg_lex("%s:%d LEX_ASSIGNxyz", __func__, __LINE__); |
| - | if (prev != XC_INST_VAR && prev != XC_INST_ARRAY_ELEM |
| - | && prev != XC_INST_SCALE && prev != XC_INST_IBASE |
| - | && prev != XC_INST_OBASE && prev != BC_INST_LAST |
| - | ) { |
| - | return bc_error("bad assignment:" |
| - | " left side must be variable" |
| - | " or array element" |
| - | ); // note: shared string |
| - | } |
| - | // Fallthrough. |
| - | case XC_LEX_OP_POWER: |
| - | case XC_LEX_OP_MULTIPLY: |
| - | case XC_LEX_OP_DIVIDE: |
| - | case XC_LEX_OP_MODULUS: |
| - | case XC_LEX_OP_PLUS: |
| - | case XC_LEX_OP_REL_EQ: |
| - | case XC_LEX_OP_REL_LE: |
| - | case XC_LEX_OP_REL_GE: |
| - | case XC_LEX_OP_REL_NE: |
| - | case XC_LEX_OP_REL_LT: |
| - | case XC_LEX_OP_REL_GT: |
| - | case BC_LEX_OP_BOOL_NOT: |
| - | case BC_LEX_OP_BOOL_OR: |
| - | case BC_LEX_OP_BOOL_AND: |
| - | dbg_lex("%s:%d LEX_OP_xyz", __func__, __LINE__); |
| - | if (((t == BC_LEX_OP_BOOL_NOT) != bin_last) |
| - | || (t != BC_LEX_OP_BOOL_NOT && prev == XC_INST_BOOL_NOT) |
| - | ) { |
| - | return bc_error_bad_expression(); |
| - | } |
| - | nrelops += (t >= XC_LEX_OP_REL_EQ && t <= XC_LEX_OP_REL_GT); |
| - | prev = BC_TOKEN_2_INST(t); |
| - | bc_parse_operator(t, ops_bgn, &nexprs); |
| - | s = zbc_lex_next(); |
| - | rprn = false; |
| - | //get_token = false; - already is |
| - | bin_last = (t != BC_LEX_OP_BOOL_NOT); |
| - | break; |
| - | case BC_LEX_LPAREN: |
| - | dbg_lex("%s:%d LEX_LPAREN", __func__, __LINE__); |
| - | if (BC_PARSE_LEAF(prev, rprn)) |
| - | return bc_error_bad_expression(); |
| - | bc_vec_push(&p->ops, &t); |
| - | nparens++; |
| - | get_token = true; |
| - | paren_expr = false; |
| - | rprn = bin_last = false; |
| - | break; |
| - | case BC_LEX_RPAREN: |
| - | dbg_lex("%s:%d LEX_RPAREN", __func__, __LINE__); |
| - | if (bin_last || prev == XC_INST_BOOL_NOT) |
| - | return bc_error_bad_expression(); |
| - | if (nparens == 0) { |
| - | goto exit_loop; |
| - | } |
| - | if (!paren_expr) { |
| - | dbg_lex_done("%s:%d done (returning EMPTY_EXP)", __func__, __LINE__); |
| - | return BC_STATUS_PARSE_EMPTY_EXP; |
| - | } |
| - | s = zbc_parse_rightParen(ops_bgn, &nexprs); |
| - | nparens--; |
| - | get_token = true; |
| - | paren_expr = rprn = true; |
| - | bin_last = false; |
| - | break; |
| - | case XC_LEX_NAME: |
| - | dbg_lex("%s:%d LEX_NAME", __func__, __LINE__); |
| - | if (BC_PARSE_LEAF(prev, rprn)) |
| - | return bc_error_bad_expression(); |
| - | s = zbc_parse_name(&prev, flags & ~BC_PARSE_NOCALL); |
| - | paren_expr = true; |
| - | rprn = bin_last = false; |
| - | //get_token = false; - already is |
| - | nexprs++; |
| - | break; |
| - | case XC_LEX_NUMBER: |
| - | dbg_lex("%s:%d LEX_NUMBER", __func__, __LINE__); |
| - | if (BC_PARSE_LEAF(prev, rprn)) |
| - | return bc_error_bad_expression(); |
| - | bc_parse_pushNUM(); |
| - | prev = XC_INST_NUM; |
| - | get_token = true; |
| - | paren_expr = true; |
| - | rprn = bin_last = false; |
| - | nexprs++; |
| - | break; |
| - | case BC_LEX_KEY_IBASE: |
| - | case BC_LEX_KEY_LAST: |
| - | case BC_LEX_KEY_OBASE: |
| - | dbg_lex("%s:%d LEX_IBASE/LAST/OBASE", __func__, __LINE__); |
| - | if (BC_PARSE_LEAF(prev, rprn)) |
| - | return bc_error_bad_expression(); |
| - | prev = (char) (t - BC_LEX_KEY_IBASE + XC_INST_IBASE); |
| - | bc_parse_push((char) prev); |
| - | get_token = true; |
| - | paren_expr = true; |
| - | rprn = bin_last = false; |
| - | nexprs++; |
| - | break; |
| - | case BC_LEX_KEY_LENGTH: |
| - | case BC_LEX_KEY_SQRT: |
| - | dbg_lex("%s:%d LEX_LEN/SQRT", __func__, __LINE__); |
| - | if (BC_PARSE_LEAF(prev, rprn)) |
| - | return bc_error_bad_expression(); |
| - | s = zbc_parse_builtin(t, flags, &prev); |
| - | get_token = true; |
| - | paren_expr = true; |
| - | rprn = bin_last = false; |
| - | nexprs++; |
| - | break; |
| - | case BC_LEX_KEY_READ: |
| - | dbg_lex("%s:%d LEX_READ", __func__, __LINE__); |
| - | if (BC_PARSE_LEAF(prev, rprn)) |
| - | return bc_error_bad_expression(); |
| - | s = zbc_parse_read(); |
| - | prev = XC_INST_READ; |
| - | get_token = true; |
| - | paren_expr = true; |
| - | rprn = bin_last = false; |
| - | nexprs++; |
| - | break; |
| - | case BC_LEX_KEY_SCALE: |
| - | dbg_lex("%s:%d LEX_SCALE", __func__, __LINE__); |
| - | if (BC_PARSE_LEAF(prev, rprn)) |
| - | return bc_error_bad_expression(); |
| - | s = zbc_parse_scale(&prev, flags); |
| - | prev = XC_INST_SCALE; |
| - | //get_token = false; - already is |
| - | paren_expr = true; |
| - | rprn = bin_last = false; |
| - | nexprs++; |
| - | break; |
| - | default: |
| - | return bc_error_bad_token(); |
| + | case BC_LEX_OP_INC: |
| + | case BC_LEX_OP_DEC: |
| + | dbg_lex("%s:%d LEX_OP_INC/DEC", __func__, __LINE__); |
| + | s = zbc_parse_incdec(&prev, &paren_expr, &nexprs, flags); |
| + | rprn = bin_last = false; |
| + | //get_token = false; - already is |
| + | break; |
| + | case XC_LEX_OP_MINUS: |
| + | dbg_lex("%s:%d LEX_OP_MINUS", __func__, __LINE__); |
| + | s = zbc_parse_minus(&prev, ops_bgn, rprn, &nexprs); |
| + | rprn = false; |
| + | //get_token = false; - already is |
| + | bin_last = (prev == XC_INST_MINUS); |
| + | break; |
| + | case BC_LEX_OP_ASSIGN_POWER: |
| + | case BC_LEX_OP_ASSIGN_MULTIPLY: |
| + | case BC_LEX_OP_ASSIGN_DIVIDE: |
| + | case BC_LEX_OP_ASSIGN_MODULUS: |
| + | case BC_LEX_OP_ASSIGN_PLUS: |
| + | case BC_LEX_OP_ASSIGN_MINUS: |
| + | case BC_LEX_OP_ASSIGN: |
| + | dbg_lex("%s:%d LEX_ASSIGNxyz", __func__, __LINE__); |
| + | if (prev != XC_INST_VAR && prev != XC_INST_ARRAY_ELEM |
| + | && prev != XC_INST_SCALE && prev != XC_INST_IBASE |
| + | && prev != XC_INST_OBASE && prev != BC_INST_LAST |
| + | ) { |
| + | return bc_error("bad assignment:" |
| + | " left side must be variable" |
| + | " or array element" |
| + | ); // note: shared string |
| + | } |
| + | // Fallthrough. |
| + | case XC_LEX_OP_POWER: |
| + | case XC_LEX_OP_MULTIPLY: |
| + | case XC_LEX_OP_DIVIDE: |
| + | case XC_LEX_OP_MODULUS: |
| + | case XC_LEX_OP_PLUS: |
| + | case XC_LEX_OP_REL_EQ: |
| + | case XC_LEX_OP_REL_LE: |
| + | case XC_LEX_OP_REL_GE: |
| + | case XC_LEX_OP_REL_NE: |
| + | case XC_LEX_OP_REL_LT: |
| + | case XC_LEX_OP_REL_GT: |
| + | case BC_LEX_OP_BOOL_NOT: |
| + | case BC_LEX_OP_BOOL_OR: |
| + | case BC_LEX_OP_BOOL_AND: |
| + | dbg_lex("%s:%d LEX_OP_xyz", __func__, __LINE__); |
| + | if (((t == BC_LEX_OP_BOOL_NOT) != bin_last) |
| + | || (t != BC_LEX_OP_BOOL_NOT && prev == XC_INST_BOOL_NOT) |
| + | ) { |
| + | return bc_error_bad_expression(); |
| + | } |
| + | nrelops += (t >= XC_LEX_OP_REL_EQ && t <= XC_LEX_OP_REL_GT); |
| + | prev = BC_TOKEN_2_INST(t); |
| + | bc_parse_operator(t, ops_bgn, &nexprs); |
| + | s = zbc_lex_next(); |
| + | rprn = false; |
| + | //get_token = false; - already is |
| + | bin_last = (t != BC_LEX_OP_BOOL_NOT); |
| + | break; |
| + | case BC_LEX_LPAREN: |
| + | dbg_lex("%s:%d LEX_LPAREN", __func__, __LINE__); |
| + | if (BC_PARSE_LEAF(prev, rprn)) |
| + | return bc_error_bad_expression(); |
| + | bc_vec_push(&p->ops, &t); |
| + | nparens++; |
| + | get_token = true; |
| + | paren_expr = false; |
| + | rprn = bin_last = false; |
| + | break; |
| + | case BC_LEX_RPAREN: |
| + | dbg_lex("%s:%d LEX_RPAREN", __func__, __LINE__); |
| + | if (bin_last || prev == XC_INST_BOOL_NOT) |
| + | return bc_error_bad_expression(); |
| + | if (nparens == 0) { |
| + | goto exit_loop; |
| + | } |
| + | if (!paren_expr) { |
| + | dbg_lex_done("%s:%d done (returning EMPTY_EXP)", __func__, __LINE__); |
| + | return BC_STATUS_PARSE_EMPTY_EXP; |
| + | } |
| + | s = zbc_parse_rightParen(ops_bgn, &nexprs); |
| + | nparens--; |
| + | get_token = true; |
| + | paren_expr = rprn = true; |
| + | bin_last = false; |
| + | break; |
| + | case XC_LEX_NAME: |
| + | dbg_lex("%s:%d LEX_NAME", __func__, __LINE__); |
| + | if (BC_PARSE_LEAF(prev, rprn)) |
| + | return bc_error_bad_expression(); |
| + | s = zbc_parse_name(&prev, flags & ~BC_PARSE_NOCALL); |
| + | paren_expr = true; |
| + | rprn = bin_last = false; |
| + | //get_token = false; - already is |
| + | nexprs++; |
| + | break; |
| + | case XC_LEX_NUMBER: |
| + | dbg_lex("%s:%d LEX_NUMBER", __func__, __LINE__); |
| + | if (BC_PARSE_LEAF(prev, rprn)) |
| + | return bc_error_bad_expression(); |
| + | bc_parse_pushNUM(); |
| + | prev = XC_INST_NUM; |
| + | get_token = true; |
| + | paren_expr = true; |
| + | rprn = bin_last = false; |
| + | nexprs++; |
| + | break; |
| + | case BC_LEX_KEY_IBASE: |
| + | case BC_LEX_KEY_LAST: |
| + | case BC_LEX_KEY_OBASE: |
| + | dbg_lex("%s:%d LEX_IBASE/LAST/OBASE", __func__, __LINE__); |
| + | if (BC_PARSE_LEAF(prev, rprn)) |
| + | return bc_error_bad_expression(); |
| + | prev = (char) (t - BC_LEX_KEY_IBASE + XC_INST_IBASE); |
| + | bc_parse_push((char) prev); |
| + | get_token = true; |
| + | paren_expr = true; |
| + | rprn = bin_last = false; |
| + | nexprs++; |
| + | break; |
| + | case BC_LEX_KEY_LENGTH: |
| + | case BC_LEX_KEY_SQRT: |
| + | dbg_lex("%s:%d LEX_LEN/SQRT", __func__, __LINE__); |
| + | if (BC_PARSE_LEAF(prev, rprn)) |
| + | return bc_error_bad_expression(); |
| + | s = zbc_parse_builtin(t, flags, &prev); |
| + | get_token = true; |
| + | paren_expr = true; |
| + | rprn = bin_last = false; |
| + | nexprs++; |
| + | break; |
| + | case BC_LEX_KEY_READ: |
| + | dbg_lex("%s:%d LEX_READ", __func__, __LINE__); |
| + | if (BC_PARSE_LEAF(prev, rprn)) |
| + | return bc_error_bad_expression(); |
| + | s = zbc_parse_read(); |
| + | prev = XC_INST_READ; |
| + | get_token = true; |
| + | paren_expr = true; |
| + | rprn = bin_last = false; |
| + | nexprs++; |
| + | break; |
| + | case BC_LEX_KEY_SCALE: |
| + | dbg_lex("%s:%d LEX_SCALE", __func__, __LINE__); |
| + | if (BC_PARSE_LEAF(prev, rprn)) |
| + | return bc_error_bad_expression(); |
| + | s = zbc_parse_scale(&prev, flags); |
| + | prev = XC_INST_SCALE; |
| + | //get_token = false; - already is |
| + | paren_expr = true; |
| + | rprn = bin_last = false; |
| + | nexprs++; |
| + | break; |
| + | default: |
| + | return bc_error_bad_token(); |
| } | |
| if (s || G_interrupt) // error, or ^C: stop parsing | |
| @@ -4913,65 +4912,65 @@ static BC_STATUS zdc_parse_token(BcLexType t) | |
| s = BC_STATUS_SUCCESS; | |
| get_token = true; | |
| switch (t) { | |
| - | case XC_LEX_OP_REL_EQ: |
| - | case XC_LEX_OP_REL_LE: |
| - | case XC_LEX_OP_REL_GE: |
| - | case XC_LEX_OP_REL_NE: |
| - | case XC_LEX_OP_REL_LT: |
| - | case XC_LEX_OP_REL_GT: |
| - | dbg_lex("%s:%d LEX_OP_REL_xyz", __func__, __LINE__); |
| - | s = zdc_parse_cond(t - XC_LEX_OP_REL_EQ + XC_INST_REL_EQ); |
| - | get_token = false; |
| - | break; |
| - | case DC_LEX_SCOLON: |
| - | case DC_LEX_COLON: |
| - | dbg_lex("%s:%d LEX_[S]COLON", __func__, __LINE__); |
| - | s = zdc_parse_mem(XC_INST_ARRAY_ELEM, true, t == DC_LEX_COLON); |
| - | break; |
| - | case XC_LEX_STR: |
| - | dbg_lex("%s:%d LEX_STR", __func__, __LINE__); |
| - | dc_parse_string(); |
| - | break; |
| - | case XC_LEX_NEG: |
| - | dbg_lex("%s:%d LEX_NEG", __func__, __LINE__); |
| - | s = zbc_lex_next(); |
| - | if (s) RETURN_STATUS(s); |
| - | if (G.prs.lex != XC_LEX_NUMBER) |
| - | RETURN_STATUS(bc_error_bad_token()); |
| - | bc_parse_pushNUM(); |
| - | bc_parse_push(XC_INST_NEG); |
| - | break; |
| - | case XC_LEX_NUMBER: |
| - | dbg_lex("%s:%d LEX_NUMBER", __func__, __LINE__); |
| - | bc_parse_pushNUM(); |
| - | break; |
| - | case DC_LEX_READ: |
| - | dbg_lex("%s:%d LEX_KEY_READ", __func__, __LINE__); |
| - | bc_parse_push(XC_INST_READ); |
| - | break; |
| - | case DC_LEX_OP_ASSIGN: |
| - | case DC_LEX_STORE_PUSH: |
| - | dbg_lex("%s:%d LEX_OP_ASSIGN/STORE_PUSH", __func__, __LINE__); |
| - | assign = (t == DC_LEX_OP_ASSIGN); |
| - | inst = assign ? XC_INST_VAR : DC_INST_PUSH_TO_VAR; |
| - | s = zdc_parse_mem(inst, true, assign); |
| - | break; |
| - | case DC_LEX_LOAD: |
| - | case DC_LEX_LOAD_POP: |
| - | dbg_lex("%s:%d LEX_OP_LOAD[_POP]", __func__, __LINE__); |
| - | inst = t == DC_LEX_LOAD_POP ? DC_INST_PUSH_VAR : DC_INST_LOAD; |
| - | s = zdc_parse_mem(inst, true, false); |
| - | break; |
| - | case DC_LEX_STORE_IBASE: |
| - | case DC_LEX_STORE_SCALE: |
| - | case DC_LEX_STORE_OBASE: |
| - | dbg_lex("%s:%d LEX_OP_STORE_I/OBASE/SCALE", __func__, __LINE__); |
| - | inst = t - DC_LEX_STORE_IBASE + XC_INST_IBASE; |
| - | s = zdc_parse_mem(inst, false, true); |
| - | break; |
| - | default: |
| - | dbg_lex_done("%s:%d done (bad token)", __func__, __LINE__); |
| + | case XC_LEX_OP_REL_EQ: |
| + | case XC_LEX_OP_REL_LE: |
| + | case XC_LEX_OP_REL_GE: |
| + | case XC_LEX_OP_REL_NE: |
| + | case XC_LEX_OP_REL_LT: |
| + | case XC_LEX_OP_REL_GT: |
| + | dbg_lex("%s:%d LEX_OP_REL_xyz", __func__, __LINE__); |
| + | s = zdc_parse_cond(t - XC_LEX_OP_REL_EQ + XC_INST_REL_EQ); |
| + | get_token = false; |
| + | break; |
| + | case DC_LEX_SCOLON: |
| + | case DC_LEX_COLON: |
| + | dbg_lex("%s:%d LEX_[S]COLON", __func__, __LINE__); |
| + | s = zdc_parse_mem(XC_INST_ARRAY_ELEM, true, t == DC_LEX_COLON); |
| + | break; |
| + | case XC_LEX_STR: |
| + | dbg_lex("%s:%d LEX_STR", __func__, __LINE__); |
| + | dc_parse_string(); |
| + | break; |
| + | case XC_LEX_NEG: |
| + | dbg_lex("%s:%d LEX_NEG", __func__, __LINE__); |
| + | s = zbc_lex_next(); |
| + | if (s) RETURN_STATUS(s); |
| + | if (G.prs.lex != XC_LEX_NUMBER) |
| RETURN_STATUS(bc_error_bad_token()); | |
| + | bc_parse_pushNUM(); |
| + | bc_parse_push(XC_INST_NEG); |
| + | break; |
| + | case XC_LEX_NUMBER: |
| + | dbg_lex("%s:%d LEX_NUMBER", __func__, __LINE__); |
| + | bc_parse_pushNUM(); |
| + | break; |
| + | case DC_LEX_READ: |
| + | dbg_lex("%s:%d LEX_KEY_READ", __func__, __LINE__); |
| + | bc_parse_push(XC_INST_READ); |
| + | break; |
| + | case DC_LEX_OP_ASSIGN: |
| + | case DC_LEX_STORE_PUSH: |
| + | dbg_lex("%s:%d LEX_OP_ASSIGN/STORE_PUSH", __func__, __LINE__); |
| + | assign = (t == DC_LEX_OP_ASSIGN); |
| + | inst = assign ? XC_INST_VAR : DC_INST_PUSH_TO_VAR; |
| + | s = zdc_parse_mem(inst, true, assign); |
| + | break; |
| + | case DC_LEX_LOAD: |
| + | case DC_LEX_LOAD_POP: |
| + | dbg_lex("%s:%d LEX_OP_LOAD[_POP]", __func__, __LINE__); |
| + | inst = t == DC_LEX_LOAD_POP ? DC_INST_PUSH_VAR : DC_INST_LOAD; |
| + | s = zdc_parse_mem(inst, true, false); |
| + | break; |
| + | case DC_LEX_STORE_IBASE: |
| + | case DC_LEX_STORE_SCALE: |
| + | case DC_LEX_STORE_OBASE: |
| + | dbg_lex("%s:%d LEX_OP_STORE_I/OBASE/SCALE", __func__, __LINE__); |
| + | inst = t - DC_LEX_STORE_IBASE + XC_INST_IBASE; |
| + | s = zdc_parse_mem(inst, false, true); |
| + | break; |
| + | default: |
| + | dbg_lex_done("%s:%d done (bad token)", __func__, __LINE__); |
| + | RETURN_STATUS(bc_error_bad_token()); |
| } | |
| if (!s && get_token) s = zbc_lex_next(); | |
| @@ -5050,62 +5049,62 @@ static BcVec* bc_program_search(char *id, bool var) | |
| static BC_STATUS zbc_program_num(BcResult *r, BcNum **num, bool hex) | |
| { | |
| switch (r->t) { | |
| - | case XC_RESULT_STR: |
| - | case XC_RESULT_TEMP: |
| - | case XC_RESULT_IBASE: |
| - | case XC_RESULT_SCALE: |
| - | case XC_RESULT_OBASE: |
| - | *num = &r->d.n; |
| - | break; |
| - | case XC_RESULT_CONSTANT: { |
| - | BcStatus s; |
| - | char *str; |
| - | unsigned base_t; |
| - | size_t len; |
| - | |
| - | str = *bc_program_const(r->d.id.idx); |
| - | len = strlen(str); |
| - | |
| - | bc_num_init(&r->d.n, len); |
| - | |
| - | hex = hex && len == 1; |
| - | base_t = hex ? 16 : G.prog.ib_t; |
| - | s = zbc_num_parse(&r->d.n, str, base_t); |
| - | if (s) { |
| - | bc_num_free(&r->d.n); |
| - | RETURN_STATUS(s); |
| - | } |
| - | *num = &r->d.n; |
| - | r->t = XC_RESULT_TEMP; |
| - | break; |
| - | } |
| - | case XC_RESULT_VAR: |
| - | case XC_RESULT_ARRAY: |
| - | case XC_RESULT_ARRAY_ELEM: { |
| - | BcVec *v; |
| + | case XC_RESULT_STR: |
| + | case XC_RESULT_TEMP: |
| + | case XC_RESULT_IBASE: |
| + | case XC_RESULT_SCALE: |
| + | case XC_RESULT_OBASE: |
| + | *num = &r->d.n; |
| + | break; |
| + | case XC_RESULT_CONSTANT: { |
| + | BcStatus s; |
| + | char *str; |
| + | unsigned base_t; |
| + | size_t len; |
| - | v = bc_program_search(r->d.id.name, r->t == XC_RESULT_VAR); |
| + | str = *bc_program_const(r->d.id.idx); |
| + | len = strlen(str); |
| - | if (r->t == XC_RESULT_ARRAY_ELEM) { |
| - | v = bc_vec_top(v); |
| - | if (v->len <= r->d.id.idx) bc_array_expand(v, r->d.id.idx + 1); |
| - | *num = bc_vec_item(v, r->d.id.idx); |
| - | } else |
| - | *num = bc_vec_top(v); |
| - | break; |
| + | bc_num_init(&r->d.n, len); |
| + | |
| + | hex = hex && len == 1; |
| + | base_t = hex ? 16 : G.prog.ib_t; |
| + | s = zbc_num_parse(&r->d.n, str, base_t); |
| + | if (s) { |
| + | bc_num_free(&r->d.n); |
| + | RETURN_STATUS(s); |
| } | |
| + | *num = &r->d.n; |
| + | r->t = XC_RESULT_TEMP; |
| + | break; |
| + | } |
| + | case XC_RESULT_VAR: |
| + | case XC_RESULT_ARRAY: |
| + | case XC_RESULT_ARRAY_ELEM: { |
| + | BcVec *v; |
| + | |
| + | v = bc_program_search(r->d.id.name, r->t == XC_RESULT_VAR); |
| + | |
| + | if (r->t == XC_RESULT_ARRAY_ELEM) { |
| + | v = bc_vec_top(v); |
| + | if (v->len <= r->d.id.idx) bc_array_expand(v, r->d.id.idx + 1); |
| + | *num = bc_vec_item(v, r->d.id.idx); |
| + | } else |
| + | *num = bc_vec_top(v); |
| + | break; |
| + | } |
| #if ENABLE_BC | |
| - | case BC_RESULT_LAST: |
| - | *num = &G.prog.last; |
| - | break; |
| - | case BC_RESULT_ONE: |
| - | *num = &G.prog.one; |
| - | break; |
| + | case BC_RESULT_LAST: |
| + | *num = &G.prog.last; |
| + | break; |
| + | case BC_RESULT_ONE: |
| + | *num = &G.prog.one; |
| + | break; |
| #endif | |
| #if SANITY_CHECKS | |
| - | default: |
| - | // Testing the theory that dc does not reach LAST/ONE |
| - | bb_error_msg_and_die("BUG:%d", r->t); |
| + | default: |
| + | // Testing the theory that dc does not reach LAST/ONE |
| + | bb_error_msg_and_die("BUG:%d", r->t); |
| #endif | |
| } | |
| @@ -6422,245 +6421,245 @@ static BC_STATUS zbc_program_exec(void) | |
| dbg_exec("inst at %zd:%d results.len:%d", ip->inst_idx - 1, inst, G.prog.results.len); | |
| switch (inst) { | |
| #if ENABLE_BC | |
| - | case BC_INST_JUMP_ZERO: { |
| - | BcNum *num; |
| - | bool zero; |
| - | dbg_exec("BC_INST_JUMP_ZERO:"); |
| - | s = zbc_program_prep(&ptr, &num); |
| - | if (s) RETURN_STATUS(s); |
| - | zero = (bc_num_cmp(num, &G.prog.zero) == 0); |
| - | bc_vec_pop(&G.prog.results); |
| - | if (!zero) { |
| - | bc_program_index(code, &ip->inst_idx); |
| - | break; |
| - | } |
| - | // else: fall through |
| - | } |
| - | case BC_INST_JUMP: { |
| - | size_t idx = bc_program_index(code, &ip->inst_idx); |
| - | size_t *addr = bc_vec_item(&func->labels, idx); |
| - | dbg_exec("BC_INST_JUMP: to %ld", (long)*addr); |
| - | ip->inst_idx = *addr; |
| + | case BC_INST_JUMP_ZERO: { |
| + | BcNum *num; |
| + | bool zero; |
| + | dbg_exec("BC_INST_JUMP_ZERO:"); |
| + | s = zbc_program_prep(&ptr, &num); |
| + | if (s) RETURN_STATUS(s); |
| + | zero = (bc_num_cmp(num, &G.prog.zero) == 0); |
| + | bc_vec_pop(&G.prog.results); |
| + | if (!zero) { |
| + | bc_program_index(code, &ip->inst_idx); |
| break; | |
| } | |
| - | case BC_INST_CALL: |
| - | dbg_exec("BC_INST_CALL:"); |
| - | s = zbc_program_call(code, &ip->inst_idx); |
| - | goto read_updated_ip; |
| - | case BC_INST_INC_PRE: |
| - | case BC_INST_DEC_PRE: |
| - | case BC_INST_INC_POST: |
| - | case BC_INST_DEC_POST: |
| - | dbg_exec("BC_INST_INCDEC:"); |
| - | s = zbc_program_incdec(inst); |
| - | break; |
| - | case BC_INST_HALT: |
| - | dbg_exec("BC_INST_HALT:"); |
| - | QUIT_OR_RETURN_TO_MAIN; |
| - | break; |
| - | case XC_INST_RET: |
| - | case BC_INST_RET0: |
| - | dbg_exec("BC_INST_RET[0]:"); |
| - | s = zbc_program_return(inst); |
| - | goto read_updated_ip; |
| - | case XC_INST_BOOL_OR: |
| - | case XC_INST_BOOL_AND: |
| + | // else: fall through |
| + | } |
| + | case BC_INST_JUMP: { |
| + | size_t idx = bc_program_index(code, &ip->inst_idx); |
| + | size_t *addr = bc_vec_item(&func->labels, idx); |
| + | dbg_exec("BC_INST_JUMP: to %ld", (long)*addr); |
| + | ip->inst_idx = *addr; |
| + | break; |
| + | } |
| + | case BC_INST_CALL: |
| + | dbg_exec("BC_INST_CALL:"); |
| + | s = zbc_program_call(code, &ip->inst_idx); |
| + | goto read_updated_ip; |
| + | case BC_INST_INC_PRE: |
| + | case BC_INST_DEC_PRE: |
| + | case BC_INST_INC_POST: |
| + | case BC_INST_DEC_POST: |
| + | dbg_exec("BC_INST_INCDEC:"); |
| + | s = zbc_program_incdec(inst); |
| + | break; |
| + | case BC_INST_HALT: |
| + | dbg_exec("BC_INST_HALT:"); |
| + | QUIT_OR_RETURN_TO_MAIN; |
| + | break; |
| + | case XC_INST_RET: |
| + | case BC_INST_RET0: |
| + | dbg_exec("BC_INST_RET[0]:"); |
| + | s = zbc_program_return(inst); |
| + | goto read_updated_ip; |
| + | case XC_INST_BOOL_OR: |
| + | case XC_INST_BOOL_AND: |
| #endif // ENABLE_BC | |
| - | case XC_INST_REL_EQ: |
| - | case XC_INST_REL_LE: |
| - | case XC_INST_REL_GE: |
| - | case XC_INST_REL_NE: |
| - | case XC_INST_REL_LT: |
| - | case XC_INST_REL_GT: |
| - | dbg_exec("BC_INST_BOOL:"); |
| - | s = zbc_program_logical(inst); |
| - | break; |
| - | case XC_INST_READ: |
| - | dbg_exec("XC_INST_READ:"); |
| - | s = zbc_program_read(); |
| - | goto read_updated_ip; |
| - | case XC_INST_VAR: |
| - | dbg_exec("XC_INST_VAR:"); |
| - | s = zbc_program_pushVar(code, &ip->inst_idx, false, false); |
| - | break; |
| - | case XC_INST_ARRAY_ELEM: |
| - | case XC_INST_ARRAY: |
| - | dbg_exec("XC_INST_ARRAY[_ELEM]:"); |
| - | s = zbc_program_pushArray(code, &ip->inst_idx, inst); |
| - | break; |
| + | case XC_INST_REL_EQ: |
| + | case XC_INST_REL_LE: |
| + | case XC_INST_REL_GE: |
| + | case XC_INST_REL_NE: |
| + | case XC_INST_REL_LT: |
| + | case XC_INST_REL_GT: |
| + | dbg_exec("BC_INST_BOOL:"); |
| + | s = zbc_program_logical(inst); |
| + | break; |
| + | case XC_INST_READ: |
| + | dbg_exec("XC_INST_READ:"); |
| + | s = zbc_program_read(); |
| + | goto read_updated_ip; |
| + | case XC_INST_VAR: |
| + | dbg_exec("XC_INST_VAR:"); |
| + | s = zbc_program_pushVar(code, &ip->inst_idx, false, false); |
| + | break; |
| + | case XC_INST_ARRAY_ELEM: |
| + | case XC_INST_ARRAY: |
| + | dbg_exec("XC_INST_ARRAY[_ELEM]:"); |
| + | s = zbc_program_pushArray(code, &ip->inst_idx, inst); |
| + | break; |
| #if ENABLE_BC | |
| - | case BC_INST_LAST: |
| - | dbg_exec("BC_INST_LAST:"); |
| - | r.t = BC_RESULT_LAST; |
| - | bc_vec_push(&G.prog.results, &r); |
| - | break; |
| + | case BC_INST_LAST: |
| + | dbg_exec("BC_INST_LAST:"); |
| + | r.t = BC_RESULT_LAST; |
| + | bc_vec_push(&G.prog.results, &r); |
| + | break; |
| #endif | |
| - | case XC_INST_IBASE: |
| - | case XC_INST_OBASE: |
| - | case XC_INST_SCALE: |
| - | dbg_exec("XC_INST_internalvar(%d):", inst - XC_INST_IBASE); |
| - | bc_program_pushGlobal(inst); |
| - | break; |
| - | case XC_INST_SCALE_FUNC: |
| - | case XC_INST_LENGTH: |
| - | case XC_INST_SQRT: |
| - | dbg_exec("BC_INST_builtin:"); |
| - | s = zbc_program_builtin(inst); |
| - | break; |
| - | case XC_INST_NUM: |
| - | dbg_exec("XC_INST_NUM:"); |
| - | r.t = XC_RESULT_CONSTANT; |
| - | r.d.id.idx = bc_program_index(code, &ip->inst_idx); |
| - | bc_vec_push(&G.prog.results, &r); |
| - | break; |
| - | case XC_INST_POP: |
| - | dbg_exec("XC_INST_POP:"); |
| - | if (!STACK_HAS_MORE_THAN(&G.prog.results, 0)) |
| - | s = bc_error_stack_has_too_few_elements(); |
| - | else |
| - | bc_vec_pop(&G.prog.results); |
| - | break; |
| - | case XC_INST_PRINT: |
| - | case XC_INST_PRINT_POP: |
| - | case XC_INST_PRINT_STR: |
| - | dbg_exec("XC_INST_PRINTxyz:"); |
| - | s = zbc_program_print(inst, 0); |
| - | break; |
| - | case XC_INST_STR: |
| - | dbg_exec("XC_INST_STR:"); |
| - | r.t = XC_RESULT_STR; |
| - | r.d.id.idx = bc_program_index(code, &ip->inst_idx); |
| - | bc_vec_push(&G.prog.results, &r); |
| - | break; |
| - | case XC_INST_POWER: |
| - | case XC_INST_MULTIPLY: |
| - | case XC_INST_DIVIDE: |
| - | case XC_INST_MODULUS: |
| - | case XC_INST_PLUS: |
| - | case XC_INST_MINUS: |
| - | dbg_exec("BC_INST_binaryop:"); |
| - | s = zbc_program_op(inst); |
| - | break; |
| - | case XC_INST_BOOL_NOT: { |
| - | BcNum *num; |
| - | dbg_exec("XC_INST_BOOL_NOT:"); |
| - | s = zbc_program_prep(&ptr, &num); |
| - | if (s) RETURN_STATUS(s); |
| - | bc_num_init_DEF_SIZE(&r.d.n); |
| - | if (bc_num_cmp(num, &G.prog.zero) == 0) |
| - | bc_num_one(&r.d.n); |
| - | //else bc_num_zero(&r.d.n); - already is |
| - | bc_program_retire(&r, XC_RESULT_TEMP); |
| - | break; |
| - | } |
| - | case XC_INST_NEG: |
| - | dbg_exec("XC_INST_NEG:"); |
| - | s = zbc_program_negate(); |
| - | break; |
| + | case XC_INST_IBASE: |
| + | case XC_INST_OBASE: |
| + | case XC_INST_SCALE: |
| + | dbg_exec("XC_INST_internalvar(%d):", inst - XC_INST_IBASE); |
| + | bc_program_pushGlobal(inst); |
| + | break; |
| + | case XC_INST_SCALE_FUNC: |
| + | case XC_INST_LENGTH: |
| + | case XC_INST_SQRT: |
| + | dbg_exec("BC_INST_builtin:"); |
| + | s = zbc_program_builtin(inst); |
| + | break; |
| + | case XC_INST_NUM: |
| + | dbg_exec("XC_INST_NUM:"); |
| + | r.t = XC_RESULT_CONSTANT; |
| + | r.d.id.idx = bc_program_index(code, &ip->inst_idx); |
| + | bc_vec_push(&G.prog.results, &r); |
| + | break; |
| + | case XC_INST_POP: |
| + | dbg_exec("XC_INST_POP:"); |
| + | if (!STACK_HAS_MORE_THAN(&G.prog.results, 0)) |
| + | s = bc_error_stack_has_too_few_elements(); |
| + | else |
| + | bc_vec_pop(&G.prog.results); |
| + | break; |
| + | case XC_INST_PRINT: |
| + | case XC_INST_PRINT_POP: |
| + | case XC_INST_PRINT_STR: |
| + | dbg_exec("XC_INST_PRINTxyz:"); |
| + | s = zbc_program_print(inst, 0); |
| + | break; |
| + | case XC_INST_STR: |
| + | dbg_exec("XC_INST_STR:"); |
| + | r.t = XC_RESULT_STR; |
| + | r.d.id.idx = bc_program_index(code, &ip->inst_idx); |
| + | bc_vec_push(&G.prog.results, &r); |
| + | break; |
| + | case XC_INST_POWER: |
| + | case XC_INST_MULTIPLY: |
| + | case XC_INST_DIVIDE: |
| + | case XC_INST_MODULUS: |
| + | case XC_INST_PLUS: |
| + | case XC_INST_MINUS: |
| + | dbg_exec("BC_INST_binaryop:"); |
| + | s = zbc_program_op(inst); |
| + | break; |
| + | case XC_INST_BOOL_NOT: { |
| + | BcNum *num; |
| + | dbg_exec("XC_INST_BOOL_NOT:"); |
| + | s = zbc_program_prep(&ptr, &num); |
| + | if (s) RETURN_STATUS(s); |
| + | bc_num_init_DEF_SIZE(&r.d.n); |
| + | if (bc_num_cmp(num, &G.prog.zero) == 0) |
| + | bc_num_one(&r.d.n); |
| + | //else bc_num_zero(&r.d.n); - already is |
| + | bc_program_retire(&r, XC_RESULT_TEMP); |
| + | break; |
| + | } |
| + | case XC_INST_NEG: |
| + | dbg_exec("XC_INST_NEG:"); |
| + | s = zbc_program_negate(); |
| + | break; |
| #if ENABLE_BC | |
| - | case BC_INST_ASSIGN_POWER: |
| - | case BC_INST_ASSIGN_MULTIPLY: |
| - | case BC_INST_ASSIGN_DIVIDE: |
| - | case BC_INST_ASSIGN_MODULUS: |
| - | case BC_INST_ASSIGN_PLUS: |
| - | case BC_INST_ASSIGN_MINUS: |
| + | case BC_INST_ASSIGN_POWER: |
| + | case BC_INST_ASSIGN_MULTIPLY: |
| + | case BC_INST_ASSIGN_DIVIDE: |
| + | case BC_INST_ASSIGN_MODULUS: |
| + | case BC_INST_ASSIGN_PLUS: |
| + | case BC_INST_ASSIGN_MINUS: |
| #endif | |
| - | case XC_INST_ASSIGN: |
| - | dbg_exec("BC_INST_ASSIGNxyz:"); |
| - | s = zbc_program_assign(inst); |
| - | break; |
| + | case XC_INST_ASSIGN: |
| + | dbg_exec("BC_INST_ASSIGNxyz:"); |
| + | s = zbc_program_assign(inst); |
| + | break; |
| #if ENABLE_DC | |
| - | case DC_INST_POP_EXEC: |
| - | dbg_exec("DC_INST_POP_EXEC:"); |
| - | bc_vec_pop(&G.prog.exestack); |
| - | goto read_updated_ip; |
| - | case DC_INST_MODEXP: |
| - | dbg_exec("DC_INST_MODEXP:"); |
| - | s = zdc_program_modexp(); |
| - | break; |
| - | case DC_INST_DIVMOD: |
| - | dbg_exec("DC_INST_DIVMOD:"); |
| - | s = zdc_program_divmod(); |
| - | break; |
| - | case DC_INST_EXECUTE: |
| - | case DC_INST_EXEC_COND: |
| - | dbg_exec("DC_INST_EXEC[_COND]:"); |
| - | s = zdc_program_execStr(code, &ip->inst_idx, inst == DC_INST_EXEC_COND); |
| - | goto read_updated_ip; |
| - | case DC_INST_PRINT_STACK: { |
| - | size_t idx; |
| - | dbg_exec("DC_INST_PRINT_STACK:"); |
| - | for (idx = 0; idx < G.prog.results.len; ++idx) { |
| - | s = zbc_program_print(XC_INST_PRINT, idx); |
| - | if (s) break; |
| - | } |
| - | break; |
| - | } |
| - | case DC_INST_CLEAR_STACK: |
| - | dbg_exec("DC_INST_CLEAR_STACK:"); |
| - | bc_vec_pop_all(&G.prog.results); |
| - | break; |
| - | case DC_INST_STACK_LEN: |
| - | dbg_exec("DC_INST_STACK_LEN:"); |
| - | dc_program_stackLen(); |
| - | break; |
| - | case DC_INST_DUPLICATE: |
| - | dbg_exec("DC_INST_DUPLICATE:"); |
| - | if (!STACK_HAS_MORE_THAN(&G.prog.results, 0)) |
| - | RETURN_STATUS(bc_error_stack_has_too_few_elements()); |
| - | ptr = bc_vec_top(&G.prog.results); |
| - | dc_result_copy(&r, ptr); |
| - | bc_vec_push(&G.prog.results, &r); |
| - | break; |
| - | case DC_INST_SWAP: { |
| - | BcResult *ptr2; |
| - | dbg_exec("DC_INST_SWAP:"); |
| - | if (!STACK_HAS_MORE_THAN(&G.prog.results, 1)) |
| - | RETURN_STATUS(bc_error_stack_has_too_few_elements()); |
| - | ptr = bc_vec_item_rev(&G.prog.results, 0); |
| - | ptr2 = bc_vec_item_rev(&G.prog.results, 1); |
| - | memcpy(&r, ptr, sizeof(BcResult)); |
| - | memcpy(ptr, ptr2, sizeof(BcResult)); |
| - | memcpy(ptr2, &r, sizeof(BcResult)); |
| - | break; |
| - | } |
| - | case DC_INST_ASCIIFY: |
| - | dbg_exec("DC_INST_ASCIIFY:"); |
| - | s = zdc_program_asciify(); |
| - | break; |
| - | case DC_INST_PRINT_STREAM: |
| - | dbg_exec("DC_INST_PRINT_STREAM:"); |
| - | s = zdc_program_printStream(); |
| - | break; |
| - | case DC_INST_LOAD: |
| - | case DC_INST_PUSH_VAR: { |
| - | bool copy = inst == DC_INST_LOAD; |
| - | s = zbc_program_pushVar(code, &ip->inst_idx, true, copy); |
| - | break; |
| - | } |
| - | case DC_INST_PUSH_TO_VAR: { |
| - | char *name = bc_program_name(code, &ip->inst_idx); |
| - | s = zbc_program_copyToVar(name, true); |
| - | free(name); |
| - | break; |
| + | case DC_INST_POP_EXEC: |
| + | dbg_exec("DC_INST_POP_EXEC:"); |
| + | bc_vec_pop(&G.prog.exestack); |
| + | goto read_updated_ip; |
| + | case DC_INST_MODEXP: |
| + | dbg_exec("DC_INST_MODEXP:"); |
| + | s = zdc_program_modexp(); |
| + | break; |
| + | case DC_INST_DIVMOD: |
| + | dbg_exec("DC_INST_DIVMOD:"); |
| + | s = zdc_program_divmod(); |
| + | break; |
| + | case DC_INST_EXECUTE: |
| + | case DC_INST_EXEC_COND: |
| + | dbg_exec("DC_INST_EXEC[_COND]:"); |
| + | s = zdc_program_execStr(code, &ip->inst_idx, inst == DC_INST_EXEC_COND); |
| + | goto read_updated_ip; |
| + | case DC_INST_PRINT_STACK: { |
| + | size_t idx; |
| + | dbg_exec("DC_INST_PRINT_STACK:"); |
| + | for (idx = 0; idx < G.prog.results.len; ++idx) { |
| + | s = zbc_program_print(XC_INST_PRINT, idx); |
| + | if (s) break; |
| } | |
| - | case DC_INST_QUIT: |
| - | dbg_exec("DC_INST_QUIT:"); |
| - | if (G.prog.exestack.len <= 2) |
| - | QUIT_OR_RETURN_TO_MAIN; |
| - | bc_vec_npop(&G.prog.exestack, 2); |
| - | goto read_updated_ip; |
| - | case DC_INST_NQUIT: |
| - | dbg_exec("DC_INST_NQUIT:"); |
| - | s = zdc_program_nquit(); |
| - | //goto read_updated_ip; - just fall through to it |
| + | break; |
| + | } |
| + | case DC_INST_CLEAR_STACK: |
| + | dbg_exec("DC_INST_CLEAR_STACK:"); |
| + | bc_vec_pop_all(&G.prog.results); |
| + | break; |
| + | case DC_INST_STACK_LEN: |
| + | dbg_exec("DC_INST_STACK_LEN:"); |
| + | dc_program_stackLen(); |
| + | break; |
| + | case DC_INST_DUPLICATE: |
| + | dbg_exec("DC_INST_DUPLICATE:"); |
| + | if (!STACK_HAS_MORE_THAN(&G.prog.results, 0)) |
| + | RETURN_STATUS(bc_error_stack_has_too_few_elements()); |
| + | ptr = bc_vec_top(&G.prog.results); |
| + | dc_result_copy(&r, ptr); |
| + | bc_vec_push(&G.prog.results, &r); |
| + | break; |
| + | case DC_INST_SWAP: { |
| + | BcResult *ptr2; |
| + | dbg_exec("DC_INST_SWAP:"); |
| + | if (!STACK_HAS_MORE_THAN(&G.prog.results, 1)) |
| + | RETURN_STATUS(bc_error_stack_has_too_few_elements()); |
| + | ptr = bc_vec_item_rev(&G.prog.results, 0); |
| + | ptr2 = bc_vec_item_rev(&G.prog.results, 1); |
| + | memcpy(&r, ptr, sizeof(BcResult)); |
| + | memcpy(ptr, ptr2, sizeof(BcResult)); |
| + | memcpy(ptr2, &r, sizeof(BcResult)); |
| + | break; |
| + | } |
| + | case DC_INST_ASCIIFY: |
| + | dbg_exec("DC_INST_ASCIIFY:"); |
| + | s = zdc_program_asciify(); |
| + | break; |
| + | case DC_INST_PRINT_STREAM: |
| + | dbg_exec("DC_INST_PRINT_STREAM:"); |
| + | s = zdc_program_printStream(); |
| + | break; |
| + | case DC_INST_LOAD: |
| + | case DC_INST_PUSH_VAR: { |
| + | bool copy = inst == DC_INST_LOAD; |
| + | s = zbc_program_pushVar(code, &ip->inst_idx, true, copy); |
| + | break; |
| + | } |
| + | case DC_INST_PUSH_TO_VAR: { |
| + | char *name = bc_program_name(code, &ip->inst_idx); |
| + | s = zbc_program_copyToVar(name, true); |
| + | free(name); |
| + | break; |
| + | } |
| + | case DC_INST_QUIT: |
| + | dbg_exec("DC_INST_QUIT:"); |
| + | if (G.prog.exestack.len <= 2) |
| + | QUIT_OR_RETURN_TO_MAIN; |
| + | bc_vec_npop(&G.prog.exestack, 2); |
| + | goto read_updated_ip; |
| + | case DC_INST_NQUIT: |
| + | dbg_exec("DC_INST_NQUIT:"); |
| + | s = zdc_program_nquit(); |
| + | //goto read_updated_ip; - just fall through to it |
| #endif // ENABLE_DC | |
| read_updated_ip: | |
| - | // Instruction stack has changed, read new pointers |
| - | ip = bc_vec_top(&G.prog.exestack); |
| - | func = bc_program_func(ip->func); |
| - | code = func->code.v; |
| - | dbg_exec("func:%zd bytes:%zd ip:%zd", ip->func, func->code.len, ip->inst_idx); |
| + | // Instruction stack has changed, read new pointers |
| + | ip = bc_vec_top(&G.prog.exestack); |
| + | func = bc_program_func(ip->func); |
| + | code = func->code.v; |
| + | dbg_exec("func:%zd bytes:%zd ip:%zd", ip->func, func->code.len, ip->inst_idx); |
| } | |
| if (s || G_interrupt) { | |