diff --git a/ast.h b/ast.h index 5899932..f6acb8e 100644 --- a/ast.h +++ b/ast.h @@ -5,6 +5,11 @@ #include +typedef struct { + size_t line; + size_t col; +} loc_t; + struct tag_expr_node; typedef struct tag_expr_node expr_node; @@ -96,6 +101,7 @@ typedef struct { typedef enum {EX_LIT, EX_LISTGEN, EX_MAPGEN, EX_BINOP, EX_UNOP, EX_INDEX, EX_SETINDEX, EX_ASSIGN, EX_REF, EX_CALL, EX_FUNCDECL} expr_t; typedef struct tag_expr_node { expr_t type; + loc_t loc; union { lit_node *lit; listgen_node *listgen; @@ -140,6 +146,7 @@ typedef struct tag_stmtlist_node { typedef enum {ST_EXPR, ST_IFELSE, ST_LOOP, ST_ITER, ST_LIST, ST_RET, ST_CONT, ST_BREAK} stmt_t; typedef struct tag_stmt_node { stmt_t type; + loc_t loc; union { expr_node *expr; ifelse_node *ifelse; @@ -155,6 +162,7 @@ typedef struct tag_stmt_node { #define AS(arg, tp) ((tp *) (arg)) #define NEW_ST() malloc(sizeof(stmt_node)) #define NEW_EX() malloc(sizeof(expr_node)) +#define SET_LOC(node, l) do { (node)->loc.line = (l).first_line; (node)->loc.col = (l).first_column; } while(0) #define NEW(arg) malloc(sizeof(arg)) #define MAKE_REF_BINOP(nd, tp, name, val) nd = NEW_EX(); \ nd->type = EX_BINOP; \ @@ -191,8 +199,8 @@ void sol_compile_free(stmt_node *); void st_free(stmt_node *); void ex_free(expr_node *); -void st_print(stmt_node *); -void ex_print(expr_node *); +void st_print(sol_state_t *, stmt_node *); +void ex_print(sol_state_t *, expr_node *); void ob_print(sol_object_t *); sol_object_t *sol_eval(sol_state_t *, expr_node *); diff --git a/astprint.c b/astprint.c index 56fc36b..922ee14 100644 --- a/astprint.c +++ b/astprint.c @@ -4,310 +4,310 @@ #include #include -void prlev(int lev, const char *fmt, ...) { +void prlev(sol_state_t *state, int lev, const char *fmt, ...) { va_list vl; int i; - for(i = 0; i < lev; i++) { putchar('|'); putchar(' '); } + for(i = 0; i < lev; i++) { sol_putchar(state, '|'); sol_putchar(state, ' '); } va_start(vl, fmt); - vprintf(fmt, vl); + sol_vprintf(state, fmt, vl); va_end(vl); - putchar('\n'); + sol_putchar(state, '\n'); } -void prex(expr_node *, int); +void prex( sol_state_t *, expr_node *, int); -void prst(stmt_node *node, int lev) { +void prst(sol_state_t *state, stmt_node *node, int lev) { if(!node) { - prlev(lev, ""); + prlev(state, lev, ""); return; } switch(node->type) { case ST_EXPR: - prlev(lev, "Stmt:"); - prex(node->expr, lev+1); + prlev(state, lev, "Stmt:"); + prex(state, node->expr, lev+1); break; case ST_IFELSE: - prlev(lev, "Stmt:"); + prlev(state, lev, "Stmt:"); lev++; - prlev(lev, "Cond:"); - prex(node->ifelse->cond, lev+1); - prlev(lev, "IfTrue:"); - prst(node->ifelse->iftrue, lev+1); - prlev(lev, "IfFalse:"); - prst(node->ifelse->iffalse, lev+1); + prlev(state, lev, "Cond:"); + prex(state, node->ifelse->cond, lev+1); + prlev(state, lev, "IfTrue:"); + prst(state, node->ifelse->iftrue, lev+1); + prlev(state, lev, "IfFalse:"); + prst(state, node->ifelse->iffalse, lev+1); break; case ST_LOOP: - prlev(lev, "Stmt:"); + prlev(state, lev, "Stmt:"); lev++; - prlev(lev, "Cond:"); - prex(node->loop->cond, lev+1); - prlev(lev, "Loop:"); - prst(node->loop->loop, lev+1); + prlev(state, lev, "Cond:"); + prex(state, node->loop->cond, lev+1); + prlev(state, lev, "Loop:"); + prst(state, node->loop->loop, lev+1); break; case ST_ITER: - prlev(lev, "Stmt:"); + prlev(state, lev, "Stmt:"); lev++; - prlev(lev, "Var: %s", node->iter->var); - prlev(lev, "Iter:"); - prex(node->iter->iter, lev+1); - prlev(lev, "Loop:"); - prst(node->iter->loop, lev+1); + prlev(state, lev, "Var: %s", node->iter->var); + prlev(state, lev, "Iter:"); + prex(state, node->iter->iter, lev+1); + prlev(state, lev, "Loop:"); + prst(state, node->iter->loop, lev+1); break; case ST_LIST: - prlev(lev, "Stmt:"); + prlev(state, lev, "Stmt:"); stmtlist_node *cur = node->stmtlist; while(cur && cur->stmt) { - prst(cur->stmt, lev+1); + prst(state, cur->stmt, lev+1); cur = cur->next; } break; case ST_RET: - prlev(lev, "Stmt:"); - prex(node->ret->ret, lev+1); + prlev(state, lev, "Stmt:"); + prex(state, node->ret->ret, lev+1); break; case ST_CONT: - prlev(lev, "Stmt"); + prlev(state, lev, "Stmt"); break; case ST_BREAK: - prlev(lev, "Stmt"); + prlev(state, lev, "Stmt"); break; } } -void prex(expr_node *node, int lev) { +void prex(sol_state_t *state, expr_node *node, int lev) { assoclist_node *cura; exprlist_node *cure; identlist_node *curi; if(!node) { - prlev(lev, ""); + prlev(state, lev, ""); return; } switch(node->type) { case EX_LIT: - prlev(lev, "Literal:"); + prlev(state, lev, "Literal:"); lev++; switch(node->lit->type) { case LIT_INT: - prlev(lev, "Int: %ld", node->lit->ival); + prlev(state, lev, "Int: %ld", node->lit->ival); break; case LIT_FLOAT: - prlev(lev, "Float: %f", node->lit->fval); + prlev(state, lev, "Float: %f", node->lit->fval); break; case LIT_STRING: - prlev(lev, "String: %s", node->lit->str); + prlev(state, lev, "String: %s", node->lit->str); break; case LIT_NONE: - prlev(lev, "None"); + prlev(state, lev, "None"); break; } break; case EX_LISTGEN: - prlev(lev, "ListGen:"); + prlev(state, lev, "ListGen:"); cure = node->listgen->list; while(cure && cure->expr) { - prex(cure->expr, lev+1); + prex(state, cure->expr, lev+1); cure = cure->next; } break; case EX_MAPGEN: - prlev(lev, "MapGen:"); + prlev(state, lev, "MapGen:"); lev++; cura = node->mapgen->map; while(cura && cura->item) { - prlev(lev, ":"); - prex(cura->item->key, lev+1); - prlev(lev, ":"); - prex(cura->item->value, lev+1); + prlev(state, lev, ":"); + prex(state, cura->item->key, lev+1); + prlev(state, lev, ":"); + prex(state, cura->item->value, lev+1); cura = cura->next; } break; case EX_BINOP: - prlev(lev, "BinOp:"); + prlev(state, lev, "BinOp:"); lev++; switch(node->binop->type) { case OP_ADD: - prlev(lev, "Op: +"); + prlev(state, lev, "Op: +"); break; case OP_SUB: - prlev(lev, "Op: -"); + prlev(state, lev, "Op: -"); break; case OP_MUL: - prlev(lev, "Op: *"); + prlev(state, lev, "Op: *"); break; case OP_DIV: - prlev(lev, "Op: /"); + prlev(state, lev, "Op: /"); break; case OP_MOD: - prlev(lev, "Op: %"); + prlev(state, lev, "Op: %"); break; case OP_POW: - prlev(lev, "Op: **"); + prlev(state, lev, "Op: **"); break; case OP_BAND: - prlev(lev, "Op: &"); + prlev(state, lev, "Op: &"); break; case OP_BOR: - prlev(lev, "Op: |"); + prlev(state, lev, "Op: |"); break; case OP_BXOR: - prlev(lev, "Op: ^"); + prlev(state, lev, "Op: ^"); break; case OP_LAND: - prlev(lev, "Op: &&"); + prlev(state, lev, "Op: &&"); break; case OP_LOR: - prlev(lev, "Op: ||"); + prlev(state, lev, "Op: ||"); break; case OP_EQUAL: - prlev(lev, "Op: =="); + prlev(state, lev, "Op: =="); break; case OP_LESS: - prlev(lev, "Op: <"); + prlev(state, lev, "Op: <"); break; case OP_GREATER: - prlev(lev, "Op: >"); + prlev(state, lev, "Op: >"); break; case OP_LESSEQ: - prlev(lev, "Op: <="); + prlev(state, lev, "Op: <="); break; case OP_GREATEREQ: - prlev(lev, "Op: >="); + prlev(state, lev, "Op: >="); break; case OP_LSHIFT: - prlev(lev, "Op: <<"); + prlev(state, lev, "Op: <<"); break; case OP_RSHIFT: - prlev(lev, "Op: >>"); + prlev(state, lev, "Op: >>"); break; } - prlev(lev, "Left:"); - prex(node->binop->left, lev+1); - prlev(lev, "Right:"); - prex(node->binop->right, lev+1); + prlev(state, lev, "Left:"); + prex(state, node->binop->left, lev+1); + prlev(state, lev, "Right:"); + prex(state, node->binop->right, lev+1); break; case EX_UNOP: - prlev(lev, "UnOp:"); + prlev(state, lev, "UnOp:"); lev++; switch(node->unop->type) { case OP_NEG: - prlev(lev, "Op: -"); + prlev(state, lev, "Op: -"); break; case OP_BNOT: - prlev(lev, "Op: ~"); + prlev(state, lev, "Op: ~"); break; case OP_LNOT: - prlev(lev, "Op: !"); + prlev(state, lev, "Op: !"); break; case OP_LEN: - prlev(lev, "Op: #"); + prlev(state, lev, "Op: #"); break; } - prlev(lev, "Expr:"); - prex(node->unop->expr, lev+1); + prlev(state, lev, "Expr:"); + prex(state, node->unop->expr, lev+1); break; case EX_INDEX: - prlev(lev, "Index:"); + prlev(state, lev, "Index:"); lev++; - prlev(lev, "Expr:"); - prex(node->index->expr, lev+1); - prlev(lev, "Index:"); - prex(node->index->index, lev+1); + prlev(state, lev, "Expr:"); + prex(state, node->index->expr, lev+1); + prlev(state, lev, "Index:"); + prex(state, node->index->index, lev+1); break; case EX_SETINDEX: - prlev(lev, "SetIndex:"); + prlev(state, lev, "SetIndex:"); lev++; - prlev(lev, "Expr:"); - prex(node->setindex->expr, lev+1); - prlev(lev, "Index:"); - prex(node->setindex->index, lev+1); - prlev(lev, "Value:"); - prex(node->setindex->value, lev+1); + prlev(state, lev, "Expr:"); + prex(state, node->setindex->expr, lev+1); + prlev(state, lev, "Index:"); + prex(state, node->setindex->index, lev+1); + prlev(state, lev, "Value:"); + prex(state, node->setindex->value, lev+1); break; case EX_ASSIGN: - prlev(lev, "Assign:"); + prlev(state, lev, "Assign:"); lev++; - prlev(lev, "Ident: %s", node->assign->ident); - prlev(lev, "Value:"); - prex(node->assign->value, lev+1); + prlev(state, lev, "Ident: %s", node->assign->ident); + prlev(state, lev, "Value:"); + prex(state, node->assign->value, lev+1); break; case EX_REF: - prlev(lev, "Ref: %s", node->ref->ident); + prlev(state, lev, "Ref: %s", node->ref->ident); break; case EX_CALL: - prlev(lev, "Call:"); + prlev(state, lev, "Call:"); lev++; - prlev(lev, "Expr:"); - prex(node->call->expr, lev+1); - prlev(lev, "Args:"); + prlev(state, lev, "Expr:"); + prex(state, node->call->expr, lev+1); + prlev(state, lev, "Args:"); cure = node->call->args; while(cure && cure->expr) { - prex(cure->expr, lev+1); + prex(state, cure->expr, lev+1); cure = cure->next; } break; case EX_FUNCDECL: - prlev(lev, "FuncDecl:"); + prlev(state, lev, "FuncDecl:"); lev++; - prlev(lev, "Name: %s", node->funcdecl->name); - prlev(lev, "Args:"); + prlev(state, lev, "Name: %s", node->funcdecl->name); + prlev(state, lev, "Args:"); curi = node->funcdecl->args; while(curi && curi->ident) { - prlev(lev+1, curi->ident); + prlev(state, lev+1, curi->ident); curi = curi->next; } - prlev(lev, "Body:"); - prst(node->funcdecl->body, lev+1); + prlev(state, lev, "Body:"); + prst(state, node->funcdecl->body, lev+1); break; } } -void st_print(stmt_node *stmt) { - prst(stmt, 0); +void st_print(sol_state_t *state, stmt_node *stmt) { + prst(state, stmt, 0); } -void ex_print(expr_node *expr) { - prex(expr, 0); +void ex_print(sol_state_t *state, expr_node *expr) { + prex(state, expr, 0); } /*int main(int argc, char **argv) { @@ -318,11 +318,11 @@ void ex_print(expr_node *expr) { if(yyparse(&program)) { printf("Syntax error (somewhere)\n"); printf("Partial tree:\n"); - prst(program, 0); + prst(state, program, 0); return 1; } - prst(program, 0); + prst(state, program, 0); return 0; }*/ diff --git a/build.sh b/build.sh index 7cc45d9..6541910 100755 --- a/build.sh +++ b/build.sh @@ -6,6 +6,7 @@ gcc -c -g lex.yy.c gcc -c -g parser.tab.c gcc -c -g astprint.c gcc -c -g runtime.c +gcc -c -g gc.c gcc -c -g object.c gcc -c -g state.c gcc -c -g builtins.c diff --git a/builtins.c b/builtins.c index b97452e..ec8f656 100644 --- a/builtins.c +++ b/builtins.c @@ -95,6 +95,7 @@ sol_object_t *sol_f_try(sol_state_t *state, sol_object_t *args) { sol_obj_free(err); sol_list_insert(state, ls, 0, zero); sol_obj_free(zero); + sol_list_insert(state, ls, 2, state->traceback); return ls; } sol_list_insert(state, ls, 0, res); @@ -207,11 +208,11 @@ void ob_print(sol_object_t *obj) { break; case SOL_STMT: - st_print(obj->node); + st_print(NULL, obj->node); //TODO: FIXME break; case SOL_EXPR: - ex_print(obj->node); + ex_print(NULL, obj->node); //TODO: FIXME break; case SOL_BUFFER: @@ -235,14 +236,17 @@ void ob_print(sol_object_t *obj) { sol_object_t *sol_f_prepr(sol_state_t *state, sol_object_t *args) { int i, sz = sol_list_len(state, args); - sol_object_t *obj; + sol_object_t *obj, *str; seen = dsl_seq_new_array(NULL, NULL); for(i=0; istr); + sol_printf(state, " "); sol_obj_free(obj); + sol_obj_free(str); } + sol_printf(state, "\n"); printf("\n"); dsl_free_seq(seen); seen = NULL; @@ -375,6 +379,39 @@ sol_object_t *sol_f_parse(sol_state_t *state, sol_object_t *args) { return sol_new_stmtnode(state, program); } +sol_object_t *sol_f_ord(sol_state_t *state, sol_object_t *args) { + sol_object_t *arg = sol_list_get_index(state, args, 0), *str = sol_cast_string(state, arg); + sol_object_t *idx = sol_new_int(state, 0), *arg2, *iarg, *res; + size_t len = strlen(str->str); + sol_obj_free(arg); + if(sol_list_len(state, args)>1) { + arg2 = sol_list_get_index(state, args, 1); + iarg = sol_cast_int(state, arg2); + sol_obj_free(arg2); + idx->ival = iarg->ival; + sol_obj_free(iarg); + } + if(idx->ival < 0 || idx->ival >= len) { + sol_obj_free(str); + sol_obj_free(idx); + return sol_set_error_string(state, "Compute ord of out-of-bounds index"); + } + res = sol_new_int(state, str->str[idx->ival]); + sol_obj_free(str); + sol_obj_free(idx); + return res; +} + +sol_object_t *sol_f_chr(sol_state_t *state, sol_object_t *args) { + sol_object_t *arg = sol_list_get_index(state, args, 0), *iarg = sol_cast_int(state, arg); + char cbuf[2]={iarg->ival, 0}; + sol_object_t *res = sol_new_string(state, cbuf); + sol_obj_free(arg); + sol_obj_free(iarg); + return res; +} + + sol_object_t *sol_f_debug_getref(sol_state_t *state, sol_object_t *args) { sol_object_t *obj = sol_list_get_index(state, args, 0); sol_object_t *res = sol_new_int(state, obj->refcnt - 2); // NB: We grabbed a reference, and there's one in the arglist, so account for them. @@ -477,6 +514,17 @@ sol_object_t *sol_f_iter_map(sol_state_t *state, sol_object_t *args) { return res; } +sol_object_t *sol_f_ast_print(sol_state_t *state, sol_object_t *args) { + sol_object_t *obj = sol_list_get_index(state, args, 0); + if(sol_is_aststmt(obj)) { + st_print(state, obj->node); + } else { + ex_print(state, obj->node); + } + sol_obj_free(obj); + return sol_incref(state->None); +} + sol_object_t *sol_f_singlet_tostring(sol_state_t *state, sol_object_t *args) { sol_object_t *obj = sol_list_get_index(state, args, 0), *res = sol_new_string(state, obj->str); sol_obj_free(obj); @@ -845,6 +893,16 @@ sol_object_t *sol_f_str_split(sol_state_t *state, sol_object_t *args) { return res; } +sol_object_t *sol_f_str_find(sol_state_t *state, sol_object_t *args) { + sol_object_t *str = sol_list_get_index(state, args, 0), *substr = sol_list_get_index(state, args, 1), *ssubstr = sol_cast_string(state, substr); + char *ptr = strstr(str->str, ssubstr->str); + sol_object_t *res = sol_new_int(state, ptr?ptr-str->str:-1); + sol_obj_free(str); + sol_obj_free(substr); + sol_obj_free(ssubstr); + return res; +} + sol_object_t *sol_f_list_add(sol_state_t *state, sol_object_t *args) { sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *ls; if(!sol_is_list(b)) { @@ -1039,22 +1097,25 @@ sol_object_t *sol_f_map_index(sol_state_t *state, sol_object_t *args) { sol_object_t *map = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1); sol_object_t *indexf = sol_map_get_name(state, map, "__index"); sol_object_t *res = NULL, *newls; - if(!sol_is_none(state, indexf)) { - if(indexf->ops->call && (sol_is_func(indexf) || sol_is_cfunc(indexf)) && indexf->ops->call != sol_f_not_impl) { - newls = sol_new_list(state); - sol_list_insert(state, newls, 0, indexf); - sol_list_append(state, newls, args); - res = indexf->ops->call(state, newls); - sol_obj_free(newls); - } else if(indexf->ops->index && indexf->ops->index != sol_f_not_impl) { - newls = sol_new_list(state); - sol_list_insert(state, newls, 0, indexf); - sol_list_insert(state, newls, 1, b); - res = indexf->ops->index(state, newls); - sol_obj_free(newls); + res = sol_map_get(state, map, b); + if(sol_is_none(state, res)) { + if(!sol_is_none(state, indexf)) { + sol_obj_free(res); + if(indexf->ops->call && (sol_is_func(indexf) || sol_is_cfunc(indexf)) && indexf->ops->call != sol_f_not_impl) { + newls = sol_new_list(state); + sol_list_insert(state, newls, 0, indexf); + sol_list_append(state, newls, args); + res = indexf->ops->call(state, newls); + sol_obj_free(newls); + } else if(indexf->ops->index && indexf->ops->index != sol_f_not_impl) { + newls = sol_new_list(state); + sol_list_insert(state, newls, 0, indexf); + sol_list_insert(state, newls, 1, b); + res = indexf->ops->index(state, newls); + sol_obj_free(newls); + } } } - if(!res) res = sol_map_get(state, map, b); sol_obj_free(indexf); sol_obj_free(map); sol_obj_free(b); @@ -1120,9 +1181,38 @@ sol_object_t *sol_f_map_iter(sol_state_t *state, sol_object_t *args) { } sol_object_t *sol_f_map_tostring(sol_state_t *state, sol_object_t *args) { - sol_object_t *cur = sol_new_string(state, "{"), *next, *str, *obj = sol_list_get_index(state, args, 0), *item; - dsl_seq_iter *iter = dsl_new_seq_iter(obj->seq); + sol_object_t *map = sol_list_get_index(state, args, 0), *res; + sol_object_t *tostrf = sol_map_get_name(state, map, "__tostring"), *fargs; + if(!sol_is_none(state, tostrf) && tostrf->ops->call) { + fargs = sol_new_list(state); + sol_list_insert(state, fargs, 0, tostrf); + sol_list_insert(state, fargs, 1, map); + res = tostrf->ops->call(state, fargs); + sol_obj_free(fargs); + } else { + res = sol_cast_repr(state, map); + } + sol_obj_free(tostrf); + sol_obj_free(map); + return res; +} + +sol_object_t *sol_f_map_repr(sol_state_t *state, sol_object_t *args) { + sol_object_t *cur = sol_new_string(state, "{"), *next, *str, *obj = sol_list_get_index(state, args, 0), *item, *reprf = sol_map_get_name(state, obj, "__repr"), *fargs; + dsl_seq_iter *iter; char s[64]; + if(!sol_is_none(state, reprf) && reprf->ops->call) { + sol_obj_free(cur); + fargs = sol_new_list(state); + sol_list_insert(state, fargs, 0, reprf); + sol_list_insert(state, fargs, 1, obj); + cur = reprf->ops->call(state, fargs); + sol_obj_free(fargs); + sol_obj_free(obj); + sol_obj_free(reprf); + return cur; + } + iter = dsl_new_seq_iter(obj->seq); while(!dsl_seq_iter_is_invalid(iter)) { item = AS_OBJ(dsl_seq_iter_at(iter)); if(test_seen(item)) { @@ -1293,6 +1383,10 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) { if(sol_is_aststmt(obj)) { if(sol_string_eq(state, str, "type")) { res = sol_new_int(state, stmt->type); + } else if(sol_string_eq(state, str, "loc")) { + res = sol_new_map(state); + sol_map_set_name(state, res, "line", sol_new_int(state, stmt->loc.line)); + sol_map_set_name(state, res, "col", sol_new_int(state, stmt->loc.col)); } else { switch(stmt->type) { case ST_EXPR: @@ -1350,6 +1444,10 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) { } else { if(sol_string_eq(state, str, "type")) { res = sol_new_int(state, expr->type); + } else if(sol_string_eq(state, str, "loc")) { + res = sol_new_map(state); + sol_map_set_name(state, res, "line", sol_new_int(state, expr->loc.line)); + sol_map_set_name(state, res, "col", sol_new_int(state, expr->loc.col)); } else { switch(expr->type) { case EX_LIT: @@ -1482,15 +1580,26 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) { stmt_node *stmt = (stmt_node *) obj->node; stmtlist_node *curs, *prevs; expr_node *expr = (expr_node *) obj->node; - exprlist_node *cure, *preve; - assoclist_node *cura, *preva; - identlist_node *curi, *previ; + exprlist_node *cure, *preve = NULL; + assoclist_node *cura, *preva = NULL; + identlist_node *curi, *previ = NULL; int i=0, len; if(sol_is_aststmt(obj)) { if(sol_string_eq(state, str, "type")) { ival = sol_cast_int(state, val); stmt->type = ival->ival; sol_obj_free(ival); + } else if(sol_string_eq(state, str, "loc") && sol_is_map(val)) { + pair = sol_map_get_name(state, val, "line"); + ival = sol_cast_int(state, pair); + stmt->loc.line = ival->ival; + sol_obj_free(ival); + sol_obj_free(pair); + pair = sol_map_get_name(state, val, "col"); + ival = sol_cast_int(state, pair); + stmt->loc.col = ival->ival; + sol_obj_free(ival); + sol_obj_free(pair); } else { switch(stmt->type) { case ST_EXPR: @@ -1543,8 +1652,9 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) { prevs->next = curs; } } + if(stmt->stmtlist == curs) stmt->stmtlist = NULL; free(curs); - prevs->next = NULL; + if(prevs) prevs->next = NULL; } else { stmt->stmtlist = NULL; } @@ -1563,6 +1673,17 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) { ival = sol_cast_int(state, val); expr->type = ival->ival; sol_obj_free(ival); + } else if(sol_string_eq(state, str, "loc") && sol_is_map(val)) { + pair = sol_map_get_name(state, val, "line"); + ival = sol_cast_int(state, pair); + expr->loc.line = ival->ival; + sol_obj_free(ival); + sol_obj_free(pair); + pair = sol_map_get_name(state, val, "col"); + ival = sol_cast_int(state, pair); + expr->loc.col = ival->ival; + sol_obj_free(ival); + sol_obj_free(pair); } else { switch(expr->type) { case EX_LIT: @@ -1592,15 +1713,16 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) { cure = malloc(sizeof(exprlist_node)); expr->listgen->list = cure; for(i=0; iexpr = sol_list_get_index(state, val, i)->node; preve = cure; cure = malloc(sizeof(exprlist_node)); preve->next = cure; } } + if(expr->listgen->list == cure) expr->listgen->list = NULL; free(cure); - preve->next = NULL; + if(preve) preve->next = NULL; } else { expr->listgen->list = NULL; } @@ -1626,8 +1748,9 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) { } } } + if(expr->mapgen->map == cura) expr->mapgen->map = NULL; free(cura); - preva->next = NULL; + if(preva) preva->next = NULL; } else { expr->mapgen->map = NULL; } @@ -1701,15 +1824,16 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) { cure = malloc(sizeof(exprlist_node)); expr->call->args= cure; for(i=0; iexpr = sol_list_get_index(state, val, i)->node; preve = cure; cure = malloc(sizeof(exprlist_node)); preve->next = cure; } } + if(expr->call->args == cure) expr->call->args = NULL; free(cure); - preve->next = NULL; + if(preve) preve->next = NULL; } else { expr->call->args = NULL; } @@ -1727,17 +1851,16 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) { curi = malloc(sizeof(identlist_node)); expr->funcdecl->args= curi; for(i=0; iident = strdup(sval->str); - sol_obj_free(sval); - previ = curi; - curi = malloc(sizeof(identlist_node)); - previ->next = curi; - } + sval = sol_cast_string(state, sol_list_get_index(state, val, i)); + curi->ident = strdup(sval->str); + sol_obj_free(sval); + previ = curi; + curi = malloc(sizeof(identlist_node)); + previ->next = curi; } + if(expr->funcdecl->args == curi) expr->funcdecl->args = NULL; free(curi); - previ->next = NULL; + if(previ) previ->next = NULL; } else { expr->funcdecl->args = NULL; } @@ -1751,11 +1874,10 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) { sol_obj_free(obj); sol_obj_free(key); sol_obj_free(str); - sol_obj_free(val); - return sol_incref(state->None); + return val; } -static char *sol_StmtNames[]={"EXPR", "IFSELSE", "LOOP", "ITER", "RET", "CONT", "BREAK"}; +static char *sol_StmtNames[]={"EXPR", "IFSELSE", "LOOP", "ITER", "LIST", "RET", "CONT", "BREAK"}; static char *sol_ExprNames[]={"LIT", "LISTGEN", "MAPGEN", "BINOP", "UNOP", "INDEX", "SETINDEX", "ASSIGN", "REF", "CALL", "FUNCDECL"}; sol_object_t *sol_f_astnode_tostring(sol_state_t *state, sol_object_t *args) { @@ -2161,7 +2283,7 @@ sol_object_t *sol_f_stream_read(sol_state_t *state, sol_object_t *args) { iamt = sol_cast_int(state, amt); s = malloc((iamt->ival + 1)*sizeof(char)); count = sol_stream_fread(state, stream, s, sizeof(char), iamt->ival); - s[iamt->ival]='\0'; + s[count]='\0'; sol_obj_free(iamt); } if(s) { @@ -2201,6 +2323,12 @@ sol_object_t *sol_f_stream_flush(sol_state_t *state, sol_object_t *args) { return res; } +sol_object_t *sol_f_stream_eof(sol_state_t *state, sol_object_t *args) { + sol_object_t *stream = sol_list_get_index(state, args, 0), *res = sol_new_int(state, sol_stream_feof(state, stream)); + sol_obj_free(stream); + return res; +} + static char *sol_FileModes[]={ NULL, "r", diff --git a/gc.c b/gc.c new file mode 100644 index 0000000..1d05707 --- /dev/null +++ b/gc.c @@ -0,0 +1,42 @@ +#include +#include "sol.h" + +#ifdef DEBUG_GC + +#else + +sol_object_t *sol_alloc_object(sol_state_t *state) { + sol_object_t *res = malloc(sizeof(sol_object_t)); + if(!res) { + sol_set_error(state, state->OutOfMemory); + return sol_incref(state->None); + } + res->refcnt = 0; + res->ops = &(state->NullOps); + return sol_incref(res); +} + +sol_object_t *sol_obj_acquire(sol_object_t *obj) { + return sol_incref(obj); +} + +void sol_obj_free(sol_object_t *obj) { + if(!obj) { + printf("WARNING: Attempt to free NULL\n"); + return; + } + if(sol_decref(obj) <= 0) { + if(obj->refcnt < 0) { + printf("WARNING: Encountered refcnt < 0!\nObject %p type %d ref %d\n", obj, obj->type, obj->refcnt); + } else { + sol_obj_release(obj); + } + } +} + +void sol_obj_release(sol_object_t *obj) { + if(obj->ops->free) obj->ops->free(NULL, obj); + free(obj); +} + +#endif \ No newline at end of file diff --git a/interp.sol b/interp.sol index c1a75e1..e85813c 100644 --- a/interp.sol +++ b/interp.sol @@ -56,6 +56,16 @@ while __interp.running do __interp.result = try(__interp.program[1]) if !__interp.result[0] then print(__interp.result[1]) + print(__interp.result[2]) + for ent in __interp.result[2] do + st = ent[0] + scope = ent[1] + if st.type == ast.ST_LIST then continue end + print('In', st, 'at', st.loc.line, ',', st.loc.col, ':') + ast.print(st) + print(scope) + print('---') + end else if __interp.isexpr then prepr(__interp.result[1]) diff --git a/lex.yy.c b/lex.yy.c index db6ca0d..5782aab 100644 --- a/lex.yy.c +++ b/lex.yy.c @@ -8,7 +8,7 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 39 +#define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -161,12 +161,7 @@ typedef unsigned int flex_uint32_t; typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -extern yy_size_t yyleng; +extern int yyleng; extern FILE *yyin, *yyout; @@ -175,7 +170,6 @@ extern FILE *yyin, *yyout; #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) - #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ @@ -193,6 +187,11 @@ extern FILE *yyin, *yyout; #define unput(c) yyunput( c, (yytext_ptr) ) +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state @@ -210,7 +209,7 @@ struct yy_buffer_state /* Number of characters read into yy_ch_buf, not including EOB * characters. */ - yy_size_t yy_n_chars; + int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to @@ -280,8 +279,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; -static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ -yy_size_t yyleng; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; @@ -309,7 +308,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); -YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); void *yyalloc (yy_size_t ); void *yyrealloc (void *,yy_size_t ); @@ -605,7 +604,7 @@ static void update_loc(YYLTYPE *yylloc, char *yytext){ . { str_putc(*yytext); } */ -#line 609 "lex.yy.c" +#line 608 "lex.yy.c" #define INITIAL 0 @@ -644,7 +643,7 @@ FILE *yyget_out (void ); void yyset_out (FILE * out_str ); -yy_size_t yyget_leng (void ); +int yyget_leng (void ); char *yyget_text (void ); @@ -806,6 +805,11 @@ YY_DECL YYLTYPE * yylloc; +#line 85 "tokenizer.lex" + + +#line 812 "lex.yy.c" + yylval = yylval_param; yylloc = yylloc_param; @@ -836,12 +840,6 @@ YY_DECL yy_load_buffer_state( ); } - { -#line 85 "tokenizer.lex" - - -#line 844 "lex.yy.c" - while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); @@ -858,7 +856,7 @@ YY_DECL yy_match: do { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; @@ -1206,7 +1204,7 @@ YY_RULE_SETUP #line 207 "tokenizer.lex" ECHO; YY_BREAK -#line 1210 "lex.yy.c" +#line 1208 "lex.yy.c" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -1337,7 +1335,6 @@ case YY_STATE_EOF(INITIAL): "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ - } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer @@ -1393,21 +1390,21 @@ static int yy_get_next_buffer (void) else { - yy_size_t num_to_read = + int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { - yy_size_t new_size = b->yy_buf_size * 2; + int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; @@ -1438,7 +1435,7 @@ static int yy_get_next_buffer (void) /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), num_to_read ); + (yy_n_chars), (size_t) num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } @@ -1533,7 +1530,7 @@ static int yy_get_next_buffer (void) yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 111); - return yy_is_jam ? 0 : yy_current_state; + return yy_is_jam ? 0 : yy_current_state; } static void yyunput (int c, register char * yy_bp ) @@ -1548,7 +1545,7 @@ static int yy_get_next_buffer (void) if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ - register yy_size_t number_to_move = (yy_n_chars) + 2; + register int number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = @@ -1597,7 +1594,7 @@ static int yy_get_next_buffer (void) else { /* need more input */ - yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); + int offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) @@ -1757,6 +1754,10 @@ static void yy_load_buffer_state (void) yyfree((void *) b ); } +#ifndef __cplusplus +extern int isatty (int ); +#endif /* __cplusplus */ + /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. @@ -1869,7 +1870,7 @@ void yypop_buffer_state (void) */ static void yyensure_buffer_stack (void) { - yy_size_t num_to_alloc; + int num_to_alloc; if (!(yy_buffer_stack)) { @@ -1966,12 +1967,12 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) * * @return the newly allocated buffer state object. */ -YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) +YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; - yy_size_t i; + int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; @@ -2053,7 +2054,7 @@ FILE *yyget_out (void) /** Get the length of the current token. * */ -yy_size_t yyget_leng (void) +int yyget_leng (void) { return yyleng; } @@ -2201,7 +2202,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 206 "tokenizer.lex" +#line 207 "tokenizer.lex" diff --git a/monty.sol b/monty.sol new file mode 100644 index 0000000..37704ca --- /dev/null +++ b/monty.sol @@ -0,0 +1,472 @@ +TOK = {LPAREN = 1, RPAREN = 2, INT = 3, BOOL = 4, NAME = 5, QUOTE = 6, EOF = 7} +keys = [] +for k in TOK do keys:insert(#keys, k) end +for k in keys do TOK[TOK[k]]=k end + +token = { + new = func (type, value) + return {type = type, value = value, __index = token} + end, + pretty = func(self) + tname = TOK[self.type] + tval = tostring(self.value) + return '{'+tname+':'+tval+'}' + end +} + +tokenizer = { + WS = " "+chr(8)+chr(9)+chr(10), + NAMESET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ=+-*/.<>?!@$%^~", + DIGITS = "0123456789", + EOF = {}, + new = func (str) + res = {str = str, pushed = None, __index = tokenizer} + res:init() + return res + end, + init = func(self) + --print('In init, self is', self) + res.cur = res:token() + res.next = res:token() + end, + next_char = func(self) + if self.pushed == None then + --print('In next_char, self is', self) + --print('In next_char, self.str is', self.str) + if self.str:eof() then return self.EOF end + res = self.str:read(1) + else + --print('Retrieving from pushback', self.pushed) + res = self.pushed[0] + self.pushed = self.pushed:sub(1) + if self.pushed == "" then self.pushed = None end + end + --print(res) + return res + end, + push_back = func(self, s) + --print('Pushing back', s) + if s == self.EOF then print('WARNING: Attempted to push_back EOF'); return end + if self.pushed == None then + self.pushed = s + else + self.pushed = s + self.pushed + end + --print('self.pushed:', self.pushed) + end, + token = func (self) + --print('In token, self is', self) + --print('In token, self.str is', self.str) + c = self:next_char() + while !(c == self.EOF) do + if c == "" then return token.new(TOK.EOF, None) end + if c == "(" then return token.new(TOK.LPAREN, c) end + if c == ")" then return token.new(TOK.RPAREN, c) end + if self.NAMESET:find(c) >= 0 then + --print('{NAME}') + name = c + c = self:next_char() + while 1 do + found = 0 + if self.NAMESET:find(c) >= 0 then found = 1 end + if self.DIGITS:find(c) >= 0 then found = 1 end + if !found then break end + name += c + c = self:next_char() + if c == self.EOF then continue end + end + self:push_back(c) + return token.new(TOK.NAME, name) + end + if self.DIGITS:find(c) >= 0 then + val = c + c = self:next_char() + while self.DIGITS:find(c) >= 0 do + val += c + c = self:next_char() + if c == self.EOF then continue end + end + self:push_back(c) + return token.new(TOK.INT, toint(val)) + end + if c == "#" then + c = self:next_char() + if c == "t" then return token.new(TOK.BOOL, 1) end + if c == "f" then return token.new(TOK.BOOL, 0) end + error("Invalid value for bool literal: "+c) + end + if c == "'" then return token.new(TOK.QUOTE, c) end + if self.WS:find(c) >= 0 then + c = self:next_char() + continue + end + if c == ";" then + c = self:next_char() + while 1 do + if c == chr(10) then break end + c = self:next_char() + end + c = self:next_char() + continue + end + error("Invalid character in token stream: "+c) + end + return token.new(TOK.EOF, None) + end, + advance = func(self) + self.cur = self.next + self.next = self:token() + end +} + + + +ttreegen = { + new = func(tok) + return {tok = tok, __index = ttreegen} + end, + generate = func(self, consume) + res = self.TT_DISPATCH[self.tok.cur.type](self, self.tok.cur) + if None == consume then self.tok:advance() end + return res + end, + TT_DISPATCH = { + [TOK.LPAREN] = func(self, tok) + toklist = [] + self.tok:advance() + tok = self.tok.cur + while 1 do + if tok.type == TOK.RPAREN then break end + if tok.type == TOK.EOF then error('Encountered EOF while matching delimiter') end + toklist:insert(#toklist, self.TT_DISPATCH[tok.type](self, tok)) + self.tok:advance() + tok = self.tok.cur + end + return toklist + end, + [TOK.RPAREN] = func(self, tok) + error("Unexpected right parenthesis") + end, + [TOK.INT] = func(self, tok) + return tok + end, + [TOK.BOOL] = func(self, tok) + return tok + end, + [TOK.NAME] = func(self, tok) + return tok + end, + [TOK.QUOTE] = func(self, tok) + self.tok:advance() + tok.quoting = self:generate(0) + return tok + end, + [TOK.EOF] = func(self, tok) + return None + end + } +} + +EX = {CALL=1, ASSIGN=2, FUNCDECL=3, SCOPE=4, IFELSE=5, DATUM=6, LIT=7, REF=8, LIST=9} +keys = [] +for k in EX do keys:insert(#keys, k) end +for k in keys do EX[EX[k]]=k end + +node = { + new = func(type, value) + return {type=type, value=value, __index=node} + end, + pretty = func(self) return self.PRETTY_DISPATCH[self.type](self) end + PRETTY_DISPATCH = { + [EX.CALL] = func(self) + return '' + end, + [EX.ASSIGN] = func(self) + return '' + end, + [EX.FUNCDECL] = func(self) + return '' + end, + [EX.SCOPE] = func(self) + return '' + end, + [EX.IFELSE] = func(self) + return '' + end, + [EX.DATUM] = func(self) + return '#'+tostring(self.value) + end, + [EX.LIT] = func(self) + if type(self.value) == 'list' then + return '/'+tostring(self.value:copy():map(func(i) return i:pretty() end)) + end + return '/'+tostring(self.value) + end, + [EX.REF] = func(self) + --print('In EX.REF, self is', self) + res = '@'+tostring(self.value) + --print('In EX.REF, returning', res) + return res + end, + [EX.LIST] = func(self) + --print('In EX.LIST, self is', self) + return '' + end + } +} + +parser = { + new = func(ttgen) + return {ttgen = ttgen, __index = parser} + end, + parse = func(self, tt) + if type(tt) == 'map' then + --print('In parse, self is', self) + --print('In parse, tt is', tt) + --print('In parse, dispatch to', self.TT_PARSE_DISPATCH[tt.type]) + res = self.TT_PARSE_DISPATCH[tt.type](self, tt) + else + name = tt[0] + if !(name.type == TOK.NAME) then + error('Expected name as first element of expression-list') + end + rest = tt:copy() + rest:remove(0) + sc = self.SCALL_DISPATCH[name.value] + if !(None == sc) then + sc = None + res = self.SCALL_DISPATCH[name.value](self, rest) + else + res = node.new(EX.CALL, {name=name.value, args=rest:map(func(i) return self:parse(i) end)}) + end + end + --print('In parse, returning', res:pretty()) + return res + end, + TT_PARSE_DISPATCH = { + [TOK.INT] = func(self, tok) + return node.new(EX.LIT, tok.value) + end, + [TOK.BOOL] = func(self, tok) + return node.new(EX.LIT, tok.value) + end, + [TOK.NAME] = func(self, tok) + --print('In TOK.NAME, tok is', tok) + res = node.new(EX.REF, tok.value) + --print('In TOK.NAME, returning', res) + return res + end, + [TOK.QUOTE] = func(self, tok) + return self:parse_datum(tok.quoting) + end + }, + SCALL_DISPATCH = { + define = func(self, args) + name = args[0] + if !(name.type == TOK.NAME) then error('Define: expected name as first argument') end + value = self:parse(args[1]) + return node.new(EX.ASSIGN, {name=name.value, value=value}) + end, + ["if"] = func(self, args) + cond = self:parse(args[0]) + ift = self:parse(args[1]) + iff = self:parse(args[2]) + return node.new(EX.IFELSE, {cond=cond, ift=ift, iff=iff}) + end, + begin = func(self, args) + args:map(func(i) return self:parse(i) end) + return node.new(EX.LIST, args) + end, + lambda = func(self, args) + --print('Lambda args:', args) + params = args[0] + if !(type(params) == 'list') then error('Lambda: expected parameters as first argument (got '+tostring(params)+')') end + params:map(func(i) + if !(type(i) == 'map') then error('Lambda: expected name token in argument list (got sublist)') end + if !(i.type == TOK.NAME) then error('Lambda: expected name token in argument list (got '+(i:pretty())+')') end + return i.value + end) + body = args:copy() + body:remove(0) + --print('Lambda body:', body) + body:map(func(i) return self:parse(i) end) + return node.new(EX.FUNCDECL, {params=params, body=node.new(EX.LIST, body)}) + end, + let = func(self, args) + defs = args[0] + if !(type(defs) == 'list') then error('Let: expected list of bindings are first argument') end + defs:map(func(i) + if !(type(i) == 'list') then error('Let: expected a binding entry') end + return self.SCALL_DISPATCH.define(self, i) + end) + body = args:copy() + body:remove(0) + body:map(func(i) return self:parse(i) end) + return node.new(EX.SCOPE, defs+body) + end, + letrec = func(self, args) + defs = args[0] + if !(type(defs) == 'list') then error('Let: expected list of bindings are first argument') end + defs:map(func(i) + if !(type(i) == 'list') then error('Let: expected a binding entry') end + return self.SCALL_DISPATCH.define(self, i) + end) + body = args:copy() + body:remove(0) + body:map(func(i) return self:parse(i) end) + return node.new(EX.LIST, defs+body) + end + } + parse_datum = func(self, tt) + if type(tt) == 'map' then + return self.TT_PARSE_DATUM_DISPATCH[tt.type](self, tt) + else + list = [] + for tok in tt do + list:insert(#list, self:parse_datum(tok)) + end + return node.new(EX.LIT, list) + end + end, + TT_PARSE_DATUM_DISPATCH = { + [TOK.INT] = func(self, tok) + return node.new(EX.LIT, tok.value) + end, + [TOK.BOOL] = func(self, tok) + return node.new(EX.LIT, tok.value) + end, + [TOK.NAME] = func(self, tok) + return node.new(EX.LIT, tok.value) + end, + [TOK.QUOTE] = func(self, tok) + return self:parse(tok.quoting) + end + }, + run = func(self) + tt = self.ttgen:generate() + list = [] + while 1 do + if None == tt then break end + --if type(tt) == 'list' then + list:insert(#list, self:parse(tt)) + --end + tt = self.ttgen:generate() + end + --print('In run, list is', list) + return node.new(EX.LIST, list) + end +} + +converter = { + new = func(p) + return {parser=p, __index = converter} + end, + make = func(self, node) + --print('In make, node is a', EX[node.type], 'of value', node) + res = self.MAKE_DISPATCH[node.type](self, node) + --print('In make, returning', res) + if type(res) == "astnode" then ast.print(res) end + return res + end, + MAKE_DISPATCH = { + [EX.CALL] = func(self, node) + e = parse('f()').stmtlist[0].expr + e.expr.ident = node.value.name + args = node.value.args:copy():map(func(i) return self:make(i) end) + --print('In EX.CALL, replacement args are', args) + e.args = args + --print('In EX.CALL, args are', e.args) + return e + end, + [EX.ASSIGN] = func(self, node) + e = parse('a = b').stmtlist[0].expr + e.ident = node.value.name + e.value = self:make(node.value.value) + return e + end, + [EX.FUNCDECL] = func(self, node) + e = parse('func() None None end').stmtlist[0].expr + params = node.value.params + --print('In EX.FUNCDECL, params are', params) + e.args = params + --print('In EX.FUNCDECL, args are', e.args) + e.body.stmtlist = self:make(node.value.body) + return e + end, + [EX.SCOPE] = func(self, node) + e = parse('(func() None None end)()').stmtlist[0].expr + node.type = EX.LIST + e.expr.body.stmtlist = self:make(node) + node.type = EX.SCOPE + return e + end, + [EX.IFELSE] = func(self, node) + e = parse('(func() if None then return None else return None end end)()').stmtlist[0].expr + e.expr.body.stmtlist[0].cond = self:make(node.value.cond) + e.expr.body.stmtlist[0].iftrue.stmtlist[0].ret = self:make(node.value.ift) + e.expr.body.stmtlist[0].iffalse.stmtlist[0].ret = self:make(node.value.iff) + return e + end, + [EX.DATUM] = func(self, node) error('EX.DATUM: Not implemented') end, + [EX.LIT] = func(self, node) + if type(node.value) == 'list' then + e = parse('[None]').stmtlist[0].expr + e.list = node.value:copy():map(func(i) return self:make(i) end) + else + e = parse('None').stmtlist[0].expr + if type(node.value) == "int" then + e.littype = ast.LIT_INT + e.ival = node.value + end + if type(node.value) == "string" then + e.littype = ast.LIT_STRING + e.str = node.value + end + end + return e + end, + [EX.REF] = func(self, node) + e = parse('a').stmtlist[0].expr + e.ident = node.value + return e + end, + [EX.LIST] = func(self, node) + e = parse('func() None end').stmtlist[0].expr + l = node.value:copy() + l:map(func(i) + s = parse('None').stmtlist[0] + s.expr = self:make(i) + return s + end) + lastidx = (#l) - 1 + r = parse('return None').stmtlist[0] + r.ret = l[lastidx].expr + l[lastidx] = r + --print('In EX.LIST, e is now' e) + e.body.stmtlist = l + return e.body.stmtlist + end + }, + run = func(self) + list = self:make(self.parser:run()) + res = parse('(func() None None end)()') + --print('In run, list is', list) + --for i in list do ast.print(i) end + res.stmtlist[0].expr.expr.body.stmtlist = list + return res + end +} + +_G = debug.globals() +_G['+'] = func(a, b) return a + b end +_G['-'] = func(a, b) return a - b end +_G['*'] = func(a, b) return a * b end +_G['/'] = func(a, b) return a / b end +_G['<'] = func(a, b) return a < b end +_G['>'] = func(a, b) return a > b end +_G['<='] = func(a, b) return a <= b end +_G['>='] = func(a, b) return a >= b end +_G['=='] = func(a, b) return a == b end +_G['eq'] = _G['=='] +_G['or'] = func(a, b) return a || b end +_G['and'] = func(a, b) return a && b end diff --git a/object.c b/object.c index 570476c..12ef848 100644 --- a/object.c +++ b/object.c @@ -55,49 +55,15 @@ sol_object_t *sol_new_singlet(sol_state_t *state, const char *name) { res->ops = &(state->SingletOps); res->str = strdup(name); } - return sol_incref(res); + return sol_incref(res); // XXX Segfault } // And, now, for the rest of the checked stuff... -sol_object_t *sol_alloc_object(sol_state_t *state) { - sol_object_t *res = malloc(sizeof(sol_object_t)); - if(!res) { - sol_set_error(state, state->OutOfMemory); - return sol_incref(state->None); - } - res->refcnt = 0; - res->ops = &(state->NullOps); - return sol_incref(res); -} - void sol_init_object(sol_state_t *state, sol_object_t *obj) { if(obj->ops->init) obj->ops->init(state, obj); } -sol_object_t *sol_obj_acquire(sol_object_t *obj) { - return sol_incref(obj); -} - -void sol_obj_free(sol_object_t *obj) { - if(!obj) { - printf("WARNING: Attempt to free NULL\n"); - return; - } - if(sol_decref(obj) <= 0) { - if(obj->refcnt < 0) { - printf("WARNING: Encountered refcnt < 0!\nObject %p type %d ref %d\n", obj, obj->type, obj->refcnt); - } else { - sol_obj_release(obj); - } - } -} - -void sol_obj_release(sol_object_t *obj) { - if(obj->ops->free) obj->ops->free(NULL, obj); - free(obj); -} - sol_object_t *sol_new_int(sol_state_t *state, long i) { sol_object_t *res = sol_alloc_object(state); res->type = SOL_INTEGER; @@ -549,7 +515,7 @@ size_t sol_stream_printf(sol_state_t *state, sol_object_t *stream, const char *f va_list va; size_t res; if(!(stream->modes & MODE_WRITE)) { - sol_obj_free(sol_set_error_string(state, "Write to non-writable stream")); + if(state) sol_obj_free(sol_set_error_string(state, "Write to non-writable stream")); return 0; } va_start(va, fmt); @@ -558,11 +524,19 @@ size_t sol_stream_printf(sol_state_t *state, sol_object_t *stream, const char *f return res; } +size_t sol_stream_vprintf(sol_state_t *state, sol_object_t *stream, const char *fmt, va_list va) { + if(!(stream->modes & MODE_WRITE)) { + if(state) sol_obj_free(sol_set_error_string(state, "Write to non-writable stream")); + return 0; + } + return vfprintf(stream->stream, fmt, va); +} + size_t sol_stream_scanf(sol_state_t *state, sol_object_t *stream, const char *fmt, ...) { va_list va; size_t res; if(!(stream->modes & MODE_READ)) { - sol_obj_free(sol_set_error_string(state, "Read from non-readable stream")); + if(state) sol_obj_free(sol_set_error_string(state, "Read from non-readable stream")); return 0; } va_start(va, fmt); @@ -573,7 +547,7 @@ size_t sol_stream_scanf(sol_state_t *state, sol_object_t *stream, const char *fm size_t sol_stream_fread(sol_state_t *state, sol_object_t *stream, char *buffer, size_t sz, size_t memb) { if(!(stream->modes & MODE_READ)) { - sol_obj_free(sol_set_error_string(state, "Read from non-readable stream")); + if(state) sol_obj_free(sol_set_error_string(state, "Read from non-readable stream")); return 0; } return fread(buffer, sz, memb, stream->stream); @@ -581,7 +555,7 @@ size_t sol_stream_fread(sol_state_t *state, sol_object_t *stream, char *buffer, size_t sol_stream_fwrite(sol_state_t *state, sol_object_t *stream, char *buffer, size_t sz, size_t memb) { if(!(stream->modes & MODE_WRITE)) { - sol_obj_free(sol_set_error_string(state, "Write to non-writable stream")); + if(state) sol_obj_free(sol_set_error_string(state, "Write to non-writable stream")); return 0; } return fwrite(buffer, sz, memb, stream->stream); @@ -589,12 +563,20 @@ size_t sol_stream_fwrite(sol_state_t *state, sol_object_t *stream, char *buffer, char *sol_stream_fgets(sol_state_t *state, sol_object_t *stream, char *buffer, size_t sz) { if(!(stream->modes & MODE_READ)) { - sol_obj_free(sol_set_error_string(state, "Read from non-readable stream")); + if(state) sol_obj_free(sol_set_error_string(state, "Read from non-readable stream")); return NULL; } return fgets(buffer, sz, stream->stream); } +int sol_stream_fputc(sol_state_t *state, sol_object_t *stream, int ch) { + if(!(stream->modes & MODE_WRITE)) { + if(state) sol_obj_free(sol_set_error_string(state, "Write to non-writable stream")); + return 0; + } + return fputc(ch, stream->stream); +} + int sol_stream_feof(sol_state_t *state, sol_object_t *stream) { return feof(stream->stream); } diff --git a/parser.output b/parser.output index 825b223..0c808d0 100644 --- a/parser.output +++ b/parser.output @@ -61,7 +61,7 @@ Grammar 1 program: stmt_list 2 stmt_list: stmt_list stmt - 3 | %empty + 3 | /* empty */ 4 stmt: expr 5 | IF expr THEN stmt_list END @@ -164,17 +164,17 @@ Grammar 85 paren_expr: LPAREN expr RPAREN - 86 expr_list: %empty + 86 expr_list: /* empty */ 87 | expr 88 | expr_list COMMA 89 | expr_list expr - 90 ident_list: %empty + 90 ident_list: /* empty */ 91 | IDENT 92 | ident_list COMMA 93 | ident_list IDENT - 94 assoc_list: %empty + 94 assoc_list: /* empty */ 95 | assoc_item 96 | assoc_list COMMA 97 | assoc_list assoc_item @@ -309,7 +309,7 @@ State 0 0 $accept: . program $end 1 program: . stmt_list 2 stmt_list: . stmt_list stmt - 3 | . %empty + 3 | . $default reduce using rule 3 (stmt_list) @@ -1122,7 +1122,7 @@ State 18 State 19 83 gen_expr: LBRACE . assoc_list RBRACE - 94 assoc_list: . %empty [IDENT, RBRACE, LBRACKET, COMMA] + 94 assoc_list: . [IDENT, RBRACE, LBRACKET, COMMA] 95 | . assoc_item 96 | . assoc_list COMMA 97 | . assoc_list assoc_item @@ -1325,7 +1325,7 @@ State 21 83 | . LBRACE assoc_list RBRACE 84 | . paren_expr 85 paren_expr: . LPAREN expr RPAREN - 86 expr_list: . %empty [FUNC, NONE, IDENT, INT, FLOAT, STRING, MINUS, BNOT, LNOT, LBRACE, LPAREN, LBRACKET, RBRACKET, COMMA, POUND] + 86 expr_list: . [FUNC, NONE, IDENT, INT, FLOAT, STRING, MINUS, BNOT, LNOT, LBRACE, LPAREN, LBRACKET, RBRACKET, COMMA, POUND] 87 | . expr 88 | . expr_list COMMA 89 | . expr_list expr @@ -1742,7 +1742,7 @@ State 45 State 46 67 funcdecl_expr: FUNC LPAREN . ident_list RPAREN stmt_list END - 90 ident_list: . %empty [IDENT, RPAREN, COMMA] + 90 ident_list: . [IDENT, RPAREN, COMMA] 91 | . IDENT 92 | . ident_list COMMA 93 | . ident_list IDENT @@ -5353,7 +5353,7 @@ State 90 83 | . LBRACE assoc_list RBRACE 84 | . paren_expr 85 paren_expr: . LPAREN expr RPAREN - 86 expr_list: . %empty [FUNC, NONE, IDENT, INT, FLOAT, STRING, MINUS, BNOT, LNOT, LBRACE, LPAREN, RPAREN, LBRACKET, COMMA, POUND] + 86 expr_list: . [FUNC, NONE, IDENT, INT, FLOAT, STRING, MINUS, BNOT, LNOT, LBRACE, LPAREN, RPAREN, LBRACKET, COMMA, POUND] 87 | . expr 88 | . expr_list COMMA 89 | . expr_list expr @@ -6408,7 +6408,7 @@ State 100 State 101 2 stmt_list: . stmt_list stmt - 3 | . %empty + 3 | . 5 stmt: IF expr THEN . stmt_list END 6 | IF expr THEN . stmt_list ELSE stmt_list END @@ -6420,7 +6420,7 @@ State 101 State 102 2 stmt_list: . stmt_list stmt - 3 | . %empty + 3 | . 7 stmt: WHILE expr DO . stmt_list END $default reduce using rule 3 (stmt_list) @@ -6541,7 +6541,7 @@ State 103 State 104 66 funcdecl_expr: FUNC IDENT LPAREN . ident_list RPAREN stmt_list END - 90 ident_list: . %empty [IDENT, RPAREN, COMMA] + 90 ident_list: . [IDENT, RPAREN, COMMA] 91 | . IDENT 92 | . ident_list COMMA 93 | . ident_list IDENT @@ -8099,7 +8099,7 @@ State 160 State 161 2 stmt_list: . stmt_list stmt - 3 | . %empty + 3 | . 67 funcdecl_expr: FUNC LPAREN ident_list RPAREN . stmt_list END $default reduce using rule 3 (stmt_list) @@ -8235,7 +8235,7 @@ State 167 83 | . LBRACE assoc_list RBRACE 84 | . paren_expr 85 paren_expr: . LPAREN expr RPAREN - 86 expr_list: . %empty [FUNC, NONE, IDENT, INT, FLOAT, STRING, MINUS, BNOT, LNOT, LBRACE, LPAREN, RPAREN, LBRACKET, COMMA, POUND] + 86 expr_list: . [FUNC, NONE, IDENT, INT, FLOAT, STRING, MINUS, BNOT, LNOT, LBRACE, LPAREN, RPAREN, LBRACKET, COMMA, POUND] 87 | . expr 88 | . expr_list COMMA 89 | . expr_list expr @@ -8293,7 +8293,7 @@ State 167 State 168 2 stmt_list: . stmt_list stmt - 3 | . %empty + 3 | . 6 stmt: IF expr THEN stmt_list ELSE . stmt_list END $default reduce using rule 3 (stmt_list) @@ -8318,7 +8318,7 @@ State 170 State 171 2 stmt_list: . stmt_list stmt - 3 | . %empty + 3 | . 8 stmt: FOR IDENT IN expr DO . stmt_list END $default reduce using rule 3 (stmt_list) @@ -8329,7 +8329,7 @@ State 171 State 172 2 stmt_list: . stmt_list stmt - 3 | . %empty + 3 | . 66 funcdecl_expr: FUNC IDENT LPAREN ident_list RPAREN . stmt_list END $default reduce using rule 3 (stmt_list) diff --git a/parser.tab.c b/parser.tab.c index 75e083e..233dc3e 100644 --- a/parser.tab.c +++ b/parser.tab.c @@ -1,19 +1,19 @@ -/* A Bison parser, made by GNU Bison 3.0.2. */ +/* A Bison parser, made by GNU Bison 2.7.12-4996. */ /* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. - + + Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -26,7 +26,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -44,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "3.0.2" +#define YYBISON_VERSION "2.7.12-4996" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -62,7 +62,8 @@ /* Copy the first part of user declarations. */ -#line 1 "parser.y" /* yacc.c:339 */ +/* Line 371 of yacc.c */ +#line 1 "parser.y" #include "sol.h" #include "ast.h" @@ -72,13 +73,14 @@ #define YYSTYPE void * -#line 76 "parser.tab.c" /* yacc.c:339 */ +/* Line 371 of yacc.c */ +#line 78 "parser.tab.c" -# ifndef YY_NULLPTR +# ifndef YY_NULL # if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULLPTR nullptr +# define YY_NULL nullptr # else -# define YY_NULLPTR 0 +# define YY_NULL 0 # endif # endif @@ -94,7 +96,7 @@ by #include "parser.tab.h". */ #ifndef YY_YY_PARSER_TAB_H_INCLUDED # define YY_YY_PARSER_TAB_H_INCLUDED -/* Debug traces. */ +/* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 1 #endif @@ -102,101 +104,114 @@ extern int yydebug; #endif -/* Token type. */ +/* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE - enum yytokentype - { - IF = 258, - THEN = 259, - ELSE = 260, - WHILE = 261, - FOR = 262, - IN = 263, - DO = 264, - FUNC = 265, - RETURN = 266, - BREAK = 267, - CONTINUE = 268, - END = 269, - NONE = 270, - IDENT = 271, - INT = 272, - FLOAT = 273, - STRING = 274, - PLUS = 275, - MINUS = 276, - STAR = 277, - SLASH = 278, - PERCENT = 279, - DSTAR = 280, - BAND = 281, - BOR = 282, - BXOR = 283, - BNOT = 284, - LAND = 285, - LOR = 286, - LNOT = 287, - ASSIGN = 288, - ASSIGNPLUS = 289, - ASSIGNMINUS = 290, - ASSIGNSTAR = 291, - ASSIGNSLASH = 292, - ASSIGNDSTAR = 293, - ASSIGNBAND = 294, - ASSIGNBOR = 295, - ASSIGNBXOR = 296, - EQUAL = 297, - LESS = 298, - GREATER = 299, - LESSEQ = 300, - GREATEREQ = 301, - RSHIFT = 302, - LSHIFT = 303, - LBRACE = 304, - RBRACE = 305, - LPAREN = 306, - RPAREN = 307, - LBRACKET = 308, - RBRACKET = 309, - DOT = 310, - COLON = 311, - SEMICOLON = 312, - COMMA = 313, - POUND = 314 - }; + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + IF = 258, + THEN = 259, + ELSE = 260, + WHILE = 261, + FOR = 262, + IN = 263, + DO = 264, + FUNC = 265, + RETURN = 266, + BREAK = 267, + CONTINUE = 268, + END = 269, + NONE = 270, + IDENT = 271, + INT = 272, + FLOAT = 273, + STRING = 274, + PLUS = 275, + MINUS = 276, + STAR = 277, + SLASH = 278, + PERCENT = 279, + DSTAR = 280, + BAND = 281, + BOR = 282, + BXOR = 283, + BNOT = 284, + LAND = 285, + LOR = 286, + LNOT = 287, + ASSIGN = 288, + ASSIGNPLUS = 289, + ASSIGNMINUS = 290, + ASSIGNSTAR = 291, + ASSIGNSLASH = 292, + ASSIGNDSTAR = 293, + ASSIGNBAND = 294, + ASSIGNBOR = 295, + ASSIGNBXOR = 296, + EQUAL = 297, + LESS = 298, + GREATER = 299, + LESSEQ = 300, + GREATEREQ = 301, + RSHIFT = 302, + LSHIFT = 303, + LBRACE = 304, + RBRACE = 305, + LPAREN = 306, + RPAREN = 307, + LBRACKET = 308, + RBRACKET = 309, + DOT = 310, + COLON = 311, + SEMICOLON = 312, + COMMA = 313, + POUND = 314 + }; #endif -/* Value type. */ + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef int YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 #endif -/* Location type. */ #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE YYLTYPE; -struct YYLTYPE +typedef struct YYLTYPE { int first_line; int first_column; int last_line; int last_column; -}; +} YYLTYPE; +# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ # define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_TRIVIAL 1 #endif - +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus int yyparse (stmt_node **program); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ #endif /* !YY_YY_PARSER_TAB_H_INCLUDED */ /* Copy the second part of user declarations. */ -#line 200 "parser.tab.c" /* yacc.c:358 */ +/* Line 390 of yacc.c */ +#line 215 "parser.tab.c" #ifdef short # undef short @@ -210,8 +225,11 @@ typedef unsigned char yytype_uint8; #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; -#else +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; +#else +typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 @@ -231,7 +249,8 @@ typedef short int yytype_int16; # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t -# elif ! defined YYSIZE_T +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else @@ -253,30 +272,11 @@ typedef short int yytype_int16; # endif #endif -#ifndef YY_ATTRIBUTE -# if (defined __GNUC__ \ - && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ - || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C -# define YY_ATTRIBUTE(Spec) __attribute__(Spec) -# else -# define YY_ATTRIBUTE(Spec) /* empty */ -# endif -#endif - -#ifndef YY_ATTRIBUTE_PURE -# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) -#endif - -#ifndef YY_ATTRIBUTE_UNUSED -# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) -#endif - -#if !defined _Noreturn \ - && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -# if defined _MSC_VER && 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) -# else -# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) +#ifndef __attribute__ +/* This feature is available in gcc versions 2.5 and later. */ +# if (! defined __GNUC__ || __GNUC__ < 2 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) +# define __attribute__(Spec) /* empty */ # endif #endif @@ -287,26 +287,25 @@ typedef short int yytype_int16; # define YYUSE(E) /* empty */ #endif -#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ - _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ - _Pragma ("GCC diagnostic pop") + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(N) (N) #else -# define YY_INITIAL_VALUE(Value) Value -#endif -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; #endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ +{ + return yyi; +} #endif - #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ @@ -324,7 +323,8 @@ typedef short int yytype_int16; # define alloca _alloca # else # define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS @@ -336,8 +336,8 @@ typedef short int yytype_int16; # endif # ifdef YYSTACK_ALLOC - /* Pacify GCC's 'empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely @@ -353,7 +353,7 @@ typedef short int yytype_int16; # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) + && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 @@ -361,13 +361,15 @@ typedef short int yytype_int16; # endif # ifndef YYMALLOC # define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS +# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS +# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif @@ -377,8 +379,8 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ + && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc @@ -404,16 +406,16 @@ union yyalloc elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) #endif @@ -432,7 +434,7 @@ union yyalloc for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ - while (0) + while (YYID (0)) # endif # endif #endif /* !YYCOPY_NEEDED */ @@ -448,19 +450,17 @@ union yyalloc #define YYNNTS 26 /* YYNRULES -- Number of rules. */ #define YYNRULES 100 -/* YYNSTATES -- Number of states. */ +/* YYNRULES -- Number of states. */ #define YYNSTATES 185 -/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 314 -#define YYTRANSLATE(YYX) \ +#define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, without out-of-bounds checking. */ +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -498,7 +498,64 @@ static const yytype_uint8 yytranslate[] = }; #if YYDEBUG - /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint16 yyprhs[] = +{ + 0, 0, 3, 5, 8, 9, 11, 17, 25, 31, + 39, 42, 44, 46, 48, 51, 55, 59, 63, 67, + 71, 75, 79, 83, 87, 91, 95, 99, 103, 107, + 111, 115, 119, 123, 125, 129, 133, 135, 138, 140, + 144, 148, 152, 156, 160, 162, 166, 170, 172, 176, + 180, 184, 186, 190, 192, 196, 200, 204, 208, 212, + 214, 217, 219, 222, 224, 229, 236, 238, 246, 253, + 255, 260, 264, 266, 271, 275, 277, 279, 281, 284, + 286, 288, 290, 292, 296, 300, 302, 306, 307, 309, + 312, 315, 316, 318, 321, 324, 325, 327, 330, 333, + 339 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 61, 0, -1, 62, -1, 62, 63, -1, -1, 64, + -1, 3, 64, 4, 62, 14, -1, 3, 64, 4, + 62, 5, 62, 14, -1, 6, 64, 9, 62, 14, + -1, 7, 16, 8, 64, 9, 62, 14, -1, 11, + 64, -1, 11, -1, 12, -1, 13, -1, 63, 57, + -1, 16, 33, 64, -1, 16, 34, 64, -1, 16, + 35, 64, -1, 16, 36, 64, -1, 16, 37, 64, + -1, 16, 38, 64, -1, 16, 39, 64, -1, 16, + 40, 64, -1, 16, 41, 64, -1, 77, 33, 64, + -1, 77, 34, 64, -1, 77, 35, 64, -1, 77, + 36, 64, -1, 77, 37, 64, -1, 77, 38, 64, + -1, 77, 39, 64, -1, 77, 40, 64, -1, 77, + 41, 64, -1, 65, -1, 65, 30, 66, -1, 65, + 31, 66, -1, 66, -1, 32, 66, -1, 67, -1, + 68, 42, 67, -1, 68, 43, 67, -1, 68, 44, + 67, -1, 68, 45, 67, -1, 68, 46, 67, -1, + 68, -1, 68, 20, 69, -1, 68, 21, 69, -1, + 69, -1, 69, 22, 70, -1, 69, 23, 70, -1, + 69, 24, 70, -1, 70, -1, 70, 25, 70, -1, + 71, -1, 71, 26, 71, -1, 71, 27, 71, -1, + 71, 28, 71, -1, 71, 48, 71, -1, 71, 47, + 71, -1, 72, -1, 29, 72, -1, 73, -1, 59, + 73, -1, 74, -1, 74, 51, 82, 52, -1, 74, + 56, 16, 51, 82, 52, -1, 75, -1, 10, 16, + 51, 83, 52, 62, 14, -1, 10, 51, 83, 52, + 62, 14, -1, 76, -1, 64, 53, 64, 54, -1, + 64, 55, 16, -1, 78, -1, 64, 53, 64, 54, + -1, 64, 55, 16, -1, 16, -1, 79, -1, 17, + -1, 21, 17, -1, 18, -1, 19, -1, 15, -1, + 80, -1, 53, 82, 54, -1, 49, 84, 50, -1, + 81, -1, 51, 64, 52, -1, -1, 64, -1, 82, + 58, -1, 82, 64, -1, -1, 16, -1, 83, 58, + -1, 83, 16, -1, -1, 85, -1, 84, 58, -1, + 84, 85, -1, 53, 64, 54, 33, 64, -1, 16, + 33, 64, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 33, 33, 37, 48, 58, 59, 60, 61, 62, @@ -533,13 +590,13 @@ static const char *const yytname[] = "power_expr", "binary_expr", "ubinary_expr", "ulen_expr", "call_expr", "funcdecl_expr", "index_expr", "ex_index_expr", "ref_expr", "lit_expr", "gen_expr", "paren_expr", "expr_list", "ident_list", "assoc_list", - "assoc_item", YY_NULLPTR + "assoc_item", YY_NULL }; #endif # ifdef YYPRINT -/* YYTOKNUM[NUM] -- (External) token number corresponding to the - (internal) symbol number NUM (which must be that of a token). */ +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, @@ -551,44 +608,41 @@ static const yytype_uint16 yytoknum[] = }; # endif -#define YYPACT_NINF -98 - -#define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-98))) - -#define YYTABLE_NINF -75 - -#define yytable_value_is_error(Yytable_value) \ - 0 +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 60, 61, 62, 62, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 65, 65, 65, 66, 66, 67, + 67, 67, 67, 67, 67, 68, 68, 68, 69, 69, + 69, 69, 70, 70, 71, 71, 71, 71, 71, 71, + 72, 72, 73, 73, 74, 74, 74, 75, 75, 75, + 76, 76, 76, 77, 77, 78, 78, 79, 79, 79, + 79, 79, 79, 80, 80, 80, 81, 82, 82, 82, + 82, 83, 83, 83, 83, 84, 84, 84, 84, 85, + 85 +}; - /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -static const yytype_int16 yypact[] = +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = { - -98, 14, 378, -98, 504, 504, 46, -8, 504, -98, - -98, -98, 175, -98, -98, -98, 13, 504, 504, 19, - 504, 504, 504, -17, 56, 7, -98, -98, 62, 127, - 45, 105, -98, -98, -15, -98, -98, 226, -98, -98, - -98, -98, 3, 2, 76, 22, 69, 56, 504, 504, - 504, 504, 504, 504, 504, 504, 504, -98, 56, 544, - -21, 70, 504, 60, -98, 47, 56, 396, 580, -98, - 504, 73, 504, 504, 504, 504, 504, 504, 504, 504, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, - 504, 101, 504, 504, 504, 504, 504, 504, 504, 504, - 504, -98, -98, 504, 69, -98, 28, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 504, 194, -98, -98, - -98, -98, -98, -98, 56, 197, 277, -98, -98, 127, - 127, 104, 104, 104, 104, 104, 45, 45, 45, 652, - 616, 616, 616, 616, 616, 441, 78, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 10, 109, 24, 29, - -98, -98, -98, 56, 103, 328, -98, 504, -98, -98, - -98, -98, -98, 174, 504, 459, 225, 276, 327, -98, - 56, -98, -98, -98, -98 + 0, 2, 1, 2, 0, 1, 5, 7, 5, 7, + 2, 1, 1, 1, 2, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 1, 3, 3, 1, 2, 1, 3, + 3, 3, 3, 3, 1, 3, 3, 1, 3, 3, + 3, 1, 3, 1, 3, 3, 3, 3, 3, 1, + 2, 1, 2, 1, 4, 6, 1, 7, 6, 1, + 4, 3, 1, 4, 3, 1, 1, 1, 2, 1, + 1, 1, 1, 3, 3, 1, 3, 0, 1, 2, + 2, 0, 1, 2, 2, 0, 1, 2, 2, 5, + 3 }; - /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE does not specify something else to do. Zero - means the default is an error. */ +/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ static const yytype_uint8 yydefact[] = { 4, 0, 2, 1, 0, 0, 0, 0, 11, 12, @@ -612,15 +666,7 @@ static const yytype_uint8 yydefact[] = 99, 65, 7, 9, 67 }; - /* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -98, -98, -97, -98, -2, -98, -6, 68, -98, 65, - 136, 111, 120, 134, -98, -98, -98, -98, -98, -98, - -98, -98, -89, 38, -98, 98 -}; - - /* YYDEFGOTO[NTERM-NUM]. */ +/* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { -1, 1, 2, 23, 58, 25, 26, 27, 28, 29, @@ -628,9 +674,44 @@ static const yytype_int8 yydefgoto[] = 40, 41, 67, 106, 63, 64 }; - /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule whose - number is the opposite. If YYTABLE_NINF, syntax error. */ +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -98 +static const yytype_int16 yypact[] = +{ + -98, 14, 378, -98, 504, 504, 46, -8, 504, -98, + -98, -98, 175, -98, -98, -98, 13, 504, 504, 19, + 504, 504, 504, -17, 56, 7, -98, -98, 62, 127, + 45, 105, -98, -98, -15, -98, -98, 226, -98, -98, + -98, -98, 3, 2, 76, 22, 69, 56, 504, 504, + 504, 504, 504, 504, 504, 504, 504, -98, 56, 544, + -21, 70, 504, 60, -98, 47, 56, 396, 580, -98, + 504, 73, 504, 504, 504, 504, 504, 504, 504, 504, + 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, + 504, 101, 504, 504, 504, 504, 504, 504, 504, 504, + 504, -98, -98, 504, 69, -98, 28, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 504, 194, -98, -98, + -98, -98, -98, -98, 56, 197, 277, -98, -98, 127, + 127, 104, 104, 104, 104, 104, 45, 45, 45, 652, + 616, 616, 616, 616, 616, 441, 78, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 10, 109, 24, 29, + -98, -98, -98, 56, 103, 328, -98, 504, -98, -98, + -98, -98, -98, 174, 504, 459, 225, 276, 327, -98, + 56, -98, -98, -98, -98 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -98, -98, -97, -98, -2, -98, -6, 68, -98, 65, + 136, 111, 120, 134, -98, -98, -98, -98, -98, -98, + -98, -98, -89, 38, -98, 98 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -75 static const yytype_int16 yytable[] = { 24, 145, 42, 43, 156, 157, 47, 101, 45, -36, @@ -706,6 +787,12 @@ static const yytype_int16 yytable[] = 0, 0, 0, 0, 0, -51, 0, -51 }; +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-98))) + +#define yytable_value_is_error(Yytable_value) \ + YYID (0) + static const yytype_int16 yycheck[] = { 2, 90, 4, 5, 101, 102, 8, 4, 16, 30, @@ -781,8 +868,8 @@ static const yytype_int16 yycheck[] = -1, -1, -1, -1, -1, 53, -1, 55 }; - /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 61, 62, 0, 3, 6, 7, 10, 11, 12, @@ -806,48 +893,30 @@ static const yytype_uint8 yystos[] = 64, 52, 14, 14, 14 }; - /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 60, 61, 62, 62, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 65, 65, 65, 66, 66, 67, - 67, 67, 67, 67, 67, 68, 68, 68, 69, 69, - 69, 69, 70, 70, 71, 71, 71, 71, 71, 71, - 72, 72, 73, 73, 74, 74, 74, 75, 75, 75, - 76, 76, 76, 77, 77, 78, 78, 79, 79, 79, - 79, 79, 79, 80, 80, 80, 81, 82, 82, 82, - 82, 83, 83, 83, 83, 84, 84, 84, 84, 85, - 85 -}; - - /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 2, 0, 1, 5, 7, 5, 7, - 2, 1, 1, 1, 2, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 1, 3, 3, 1, 2, 1, 3, - 3, 3, 3, 3, 1, 3, 3, 1, 3, 3, - 3, 1, 3, 1, 3, 3, 3, 3, 3, 1, - 2, 1, 2, 1, 4, 6, 1, 7, 6, 1, - 4, 3, 1, 4, 3, 1, 1, 1, 2, 1, - 1, 1, 1, 3, 3, 1, 3, 0, 1, 2, - 2, 0, 1, 2, 2, 0, 1, 2, 2, 5, - 3 -}; - - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif #define YYRECOVERING() (!!yyerrstatus) @@ -864,13 +933,13 @@ do \ else \ { \ yyerror (&yylloc, program, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) + YYERROR; \ + } \ +while (YYID (0)) /* Error token number */ -#define YYTERROR 1 -#define YYERRCODE 256 +#define YYTERROR 1 +#define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. @@ -880,7 +949,7 @@ while (0) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ - if (N) \ + if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ @@ -894,27 +963,12 @@ while (0) (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ - while (0) + while (YYID (0)) #endif #define YYRHSLOC(Rhs, K) ((Rhs)[K]) -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - - /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ @@ -924,28 +978,36 @@ do { \ /* Print *YYLOCP on YYO. Private, do not rely on its existence. */ -YY_ATTRIBUTE_UNUSED +__attribute__((__unused__)) +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) static unsigned yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) +#else +static unsigned +yy_location_print_ (yyo, yylocp) + FILE *yyo; + YYLTYPE const * const yylocp; +#endif { unsigned res = 0; int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; if (0 <= yylocp->first_line) { - res += YYFPRINTF (yyo, "%d", yylocp->first_line); + res += fprintf (yyo, "%d", yylocp->first_line); if (0 <= yylocp->first_column) - res += YYFPRINTF (yyo, ".%d", yylocp->first_column); + res += fprintf (yyo, ".%d", yylocp->first_column); } if (0 <= yylocp->last_line) { if (yylocp->first_line < yylocp->last_line) { - res += YYFPRINTF (yyo, "-%d", yylocp->last_line); + res += fprintf (yyo, "-%d", yylocp->last_line); if (0 <= end_col) - res += YYFPRINTF (yyo, ".%d", end_col); + res += fprintf (yyo, ".%d", end_col); } else if (0 <= end_col && yylocp->first_column < end_col) - res += YYFPRINTF (yyo, "-%d", end_col); + res += fprintf (yyo, "-%d", end_col); } return res; } @@ -959,34 +1021,69 @@ yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) #endif -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, Location, program); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) +/* YYLEX -- calling `yylex' with the right arguments. */ +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval, &yylloc) +#endif +/* Enable debugging if requested. */ +#if YYDEBUG -/*----------------------------------------. -| Print this symbol's value on YYOUTPUT. | -`----------------------------------------*/ +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, Location, program); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, stmt_node **program) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, program) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + YYLTYPE const * const yylocationp; + stmt_node **program; +#endif { FILE *yyo = yyoutput; YYUSE (yyo); - YYUSE (yylocationp); - YYUSE (program); if (!yyvaluep) return; + YYUSE (yylocationp); + YYUSE (program); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); # endif YYUSE (yytype); } @@ -996,11 +1093,24 @@ yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvalue | Print this symbol on YYOUTPUT. | `--------------------------------*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, stmt_node **program) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, program) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + YYLTYPE const * const yylocationp; + stmt_node **program; +#endif { - YYFPRINTF (yyoutput, "%s %s (", - yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); YY_LOCATION_PRINT (yyoutput, *yylocationp); YYFPRINTF (yyoutput, ": "); @@ -1013,8 +1123,16 @@ yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYL | TOP (included). | `------------------------------------------------------------------*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) @@ -1025,42 +1143,51 @@ yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) YYFPRINTF (stderr, "\n"); } -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, stmt_node **program) +#else static void -yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, stmt_node **program) +yy_reduce_print (yyvsp, yylsp, yyrule, program) + YYSTYPE *yyvsp; + YYLTYPE *yylsp; + int yyrule; + stmt_node **program; +#endif { - unsigned long int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; + unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); + yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, - yystos[yyssp[yyi + 1 - yynrhs]], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , &(yylsp[(yyi + 1) - (yynrhs)]) , program); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + , &(yylsp[(yyi + 1) - (yynrhs)]) , program); YYFPRINTF (stderr, "\n"); } } -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyssp, yyvsp, yylsp, Rule, program); \ -} while (0) +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, yylsp, Rule, program); \ +} while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ @@ -1074,7 +1201,7 @@ int yydebug; /* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH +#ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif @@ -1097,8 +1224,15 @@ int yydebug; # define yystrlen strlen # else /* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) @@ -1114,8 +1248,16 @@ yystrlen (const char *yystr) # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif { char *yyd = yydest; const char *yys = yysrc; @@ -1145,27 +1287,27 @@ yytnamerr (char *yyres, const char *yystr) char const *yyp = yystr; for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } do_not_strip_quotes: ; } @@ -1188,11 +1330,11 @@ static int yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yytype_int16 *yyssp, int yytoken) { - YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); + YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); YYSIZE_T yysize = yysize0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ - const char *yyformat = YY_NULLPTR; + const char *yyformat = YY_NULL; /* Arguments of yyformat. */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Number of reported tokens (one for the "unexpected", one per @@ -1200,6 +1342,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, int yycount = 0; /* There are many possibilities here to consider: + - Assume YYFAIL is not used. It's too flawed to consider. See + + for details. YYERROR is fine as it does not invoke this + function. - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected @@ -1249,7 +1395,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, } yyarg[yycount++] = yytname[yyx]; { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; @@ -1316,19 +1462,30 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, | Release the memory associated to this symbol. | `-----------------------------------------------*/ +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, stmt_node **program) +#else +static void +yydestruct (yymsg, yytype, yyvaluep, yylocationp, program) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; + YYLTYPE *yylocationp; + stmt_node **program; +#endif { YYUSE (yyvaluep); YYUSE (yylocationp); YYUSE (program); + if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YYUSE (yytype); - YY_IGNORE_MAYBE_UNINITIALIZED_END } @@ -1338,27 +1495,66 @@ yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocatio | yyparse. | `----------*/ +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) int yyparse (stmt_node **program) +#else +int +yyparse (program) + stmt_node **program; +#endif +#endif { /* The lookahead symbol. */ int yychar; -/* The semantic value of the lookahead symbol. */ +#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else /* Default value used for initialization, for pacifying older GCCs or non-GCC compilers. */ -YY_INITIAL_VALUE (static YYSTYPE yyval_default;) -YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); - -/* Location data for the lookahead symbol. */ +static YYSTYPE yyval_default; +# define YY_INITIAL_VALUE(Value) = Value +#endif static YYLTYPE yyloc_default # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL = { 1, 1, 1, 1 } # endif ; +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval YY_INITIAL_VALUE(yyval_default); + +/* Location data for the lookahead symbol. */ YYLTYPE yylloc = yyloc_default; + /* Number of syntax errors so far. */ int yynerrs; @@ -1367,9 +1563,9 @@ YYLTYPE yylloc = yyloc_default; int yyerrstatus; /* The stacks and their tools: - 'yyss': related to states. - 'yyvs': related to semantic values. - 'yyls': related to locations. + `yyss': related to states. + `yyvs': related to semantic values. + `yyls': related to locations. Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ @@ -1448,26 +1644,26 @@ YYLTYPE yylloc = yyloc_default; #ifdef yyoverflow { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - YYLTYPE *yyls1 = yyls; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), - &yystacksize); - - yyls = yyls1; - yyss = yyss1; - yyvs = yyvs1; + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + YYLTYPE *yyls1 = yyls; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yyls1, yysize * sizeof (*yylsp), + &yystacksize); + + yyls = yyls1; + yyss = yyss1; + yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE @@ -1475,23 +1671,23 @@ YYLTYPE yylloc = yyloc_default; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; + goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; + yystacksize = YYMAXDEPTH; { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); - YYSTACK_RELOCATE (yyls_alloc, yyls); + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); + YYSTACK_RELOCATE (yyls_alloc, yyls); # undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ @@ -1501,10 +1697,10 @@ YYLTYPE yylloc = yyloc_default; yylsp = yyls + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) - YYABORT; + YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); @@ -1533,7 +1729,7 @@ yybackup: if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); - yychar = yylex (&yylval, &yylloc); + yychar = YYLEX; } if (yychar <= YYEOF) @@ -1598,7 +1794,7 @@ yyreduce: yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: - '$$ = $1'. + `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison @@ -1613,29 +1809,30 @@ yyreduce: switch (yyn) { case 2: -#line 33 "parser.y" /* yacc.c:1646 */ - { *program = AS_ST((yyvsp[0])); } -#line 1619 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 33 "parser.y" + { *program = AS_ST((yyvsp[(1) - (1)])); } break; case 3: -#line 37 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 37 "parser.y" { - stmtlist_node *cur = AS_ST((yyvsp[-1]))->stmtlist; + stmtlist_node *cur = AS_ST((yyvsp[(1) - (2)]))->stmtlist; while(cur->next) cur = cur->next; if(cur->stmt) { cur->next = NEW(stmtlist_node); cur = cur->next; } - cur->stmt = (yyvsp[0]); + cur->stmt = (yyvsp[(2) - (2)]); cur->next = NULL; - (yyval) = (yyvsp[-1]); + (yyval) = (yyvsp[(1) - (2)]); } -#line 1635 "parser.tab.c" /* yacc.c:1646 */ break; case 4: -#line 48 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 48 "parser.y" { (yyval) = NEW_ST(); AS_ST((yyval))->type = ST_LIST; @@ -1643,527 +1840,527 @@ yyreduce: AS_ST((yyval))->stmtlist->stmt = NULL; AS_ST((yyval))->stmtlist->next = NULL; } -#line 1647 "parser.tab.c" /* yacc.c:1646 */ break; case 5: -#line 58 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_ST(); AS_ST((yyval))->type = ST_EXPR; AS_ST((yyval))->expr = (yyvsp[0]); } -#line 1653 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 58 "parser.y" + { (yyval) = NEW_ST(); SET_LOC(AS_ST((yyval)), (yyloc)); AS_ST((yyval))->type = ST_EXPR; AS_ST((yyval))->expr = (yyvsp[(1) - (1)]); } break; case 6: -#line 59 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_ST(); AS_ST((yyval))->type = ST_IFELSE; AS_ST((yyval))->ifelse = NEW(ifelse_node); AS_ST((yyval))->ifelse->cond = (yyvsp[-3]); AS_ST((yyval))->ifelse->iftrue = (yyvsp[-1]); AS_ST((yyval))->ifelse->iffalse = NULL; } -#line 1659 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 59 "parser.y" + { (yyval) = NEW_ST(); SET_LOC(AS_ST((yyval)), (yyloc)); AS_ST((yyval))->type = ST_IFELSE; AS_ST((yyval))->ifelse = NEW(ifelse_node); AS_ST((yyval))->ifelse->cond = (yyvsp[(2) - (5)]); AS_ST((yyval))->ifelse->iftrue = (yyvsp[(4) - (5)]); AS_ST((yyval))->ifelse->iffalse = NULL; } break; case 7: -#line 60 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_ST(); AS_ST((yyval))->type = ST_IFELSE; AS_ST((yyval))->ifelse = NEW(ifelse_node); AS_ST((yyval))->ifelse->cond = (yyvsp[-5]); AS_ST((yyval))->ifelse->iftrue = (yyvsp[-3]); AS_ST((yyval))->ifelse->iffalse = (yyvsp[-1]); } -#line 1665 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 60 "parser.y" + { (yyval) = NEW_ST(); SET_LOC(AS_ST((yyval)), (yyloc)); AS_ST((yyval))->type = ST_IFELSE; AS_ST((yyval))->ifelse = NEW(ifelse_node); AS_ST((yyval))->ifelse->cond = (yyvsp[(2) - (7)]); AS_ST((yyval))->ifelse->iftrue = (yyvsp[(4) - (7)]); AS_ST((yyval))->ifelse->iffalse = (yyvsp[(6) - (7)]); } break; case 8: -#line 61 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_ST(); AS_ST((yyval))->type = ST_LOOP; AS_ST((yyval))->loop = NEW(loop_node); AS_ST((yyval))->loop->cond = (yyvsp[-3]); AS_ST((yyval))->loop->loop = (yyvsp[-1]); } -#line 1671 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 61 "parser.y" + { (yyval) = NEW_ST(); SET_LOC(AS_ST((yyval)), (yyloc)); AS_ST((yyval))->type = ST_LOOP; AS_ST((yyval))->loop = NEW(loop_node); AS_ST((yyval))->loop->cond = (yyvsp[(2) - (5)]); AS_ST((yyval))->loop->loop = (yyvsp[(4) - (5)]); } break; case 9: -#line 62 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_ST(); AS_ST((yyval))->type = ST_ITER; AS_ST((yyval))->iter = NEW(iter_node); AS_ST((yyval))->iter->var = (yyvsp[-5]); AS_ST((yyval))->iter->iter = (yyvsp[-3]); AS_ST((yyval))->iter->loop = (yyvsp[-1]); } -#line 1677 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 62 "parser.y" + { (yyval) = NEW_ST(); SET_LOC(AS_ST((yyval)), (yyloc)); AS_ST((yyval))->type = ST_ITER; AS_ST((yyval))->iter = NEW(iter_node); AS_ST((yyval))->iter->var = (yyvsp[(2) - (7)]); AS_ST((yyval))->iter->iter = (yyvsp[(4) - (7)]); AS_ST((yyval))->iter->loop = (yyvsp[(6) - (7)]); } break; case 10: -#line 63 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_ST(); AS_ST((yyval))->type = ST_RET; AS_ST((yyval))->ret = NEW(ret_node); AS_ST((yyval))->ret->ret = (yyvsp[0]); } -#line 1683 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 63 "parser.y" + { (yyval) = NEW_ST(); SET_LOC(AS_ST((yyval)), (yyloc)); AS_ST((yyval))->type = ST_RET; AS_ST((yyval))->ret = NEW(ret_node); AS_ST((yyval))->ret->ret = (yyvsp[(2) - (2)]); } break; case 11: -#line 64 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_ST(); AS_ST((yyval))->type = ST_RET; AS_ST((yyval))->ret = NEW(ret_node); AS_ST((yyval))->ret->ret = NULL; } -#line 1689 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 64 "parser.y" + { (yyval) = NEW_ST(); SET_LOC(AS_ST((yyval)), (yyloc)); AS_ST((yyval))->type = ST_RET; AS_ST((yyval))->ret = NEW(ret_node); AS_ST((yyval))->ret->ret = NULL; } break; case 12: -#line 65 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_ST(); AS_ST((yyval))->type = ST_BREAK; } -#line 1695 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 65 "parser.y" + { (yyval) = NEW_ST(); SET_LOC(AS_ST((yyval)), (yyloc)); AS_ST((yyval))->type = ST_BREAK; } break; case 13: -#line 66 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_ST(); AS_ST((yyval))->type = ST_CONT; } -#line 1701 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 66 "parser.y" + { (yyval) = NEW_ST(); SET_LOC(AS_ST((yyval)), (yyloc)); AS_ST((yyval))->type = ST_CONT; } break; case 14: -#line 67 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[-1]); } -#line 1707 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 67 "parser.y" + { (yyval) = (yyvsp[(1) - (2)]); } break; case 15: -#line 71 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_ASSIGN; AS_EX((yyval))->assign = NEW(assign_node); AS_EX((yyval))->assign->ident = (yyvsp[-2]); AS_EX((yyval))->assign->value = (yyvsp[0]); } -#line 1713 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 71 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_ASSIGN; AS_EX((yyval))->assign = NEW(assign_node); AS_EX((yyval))->assign->ident = (yyvsp[(1) - (3)]); AS_EX((yyval))->assign->value = (yyvsp[(3) - (3)]); } break; case 16: -#line 72 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 72 "parser.y" { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_ASSIGN; AS_EX((yyval))->assign = NEW(assign_node); - AS_EX((yyval))->assign->ident = (yyvsp[-2]); - MAKE_REF_BINOP(AS_EX((yyval))->assign->value, OP_ADD, (yyvsp[-2]), (yyvsp[0])); + AS_EX((yyval))->assign->ident = (yyvsp[(1) - (3)]); + MAKE_REF_BINOP(AS_EX((yyval))->assign->value, OP_ADD, (yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])); } -#line 1725 "parser.tab.c" /* yacc.c:1646 */ break; case 17: -#line 79 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 79 "parser.y" { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_ASSIGN; AS_EX((yyval))->assign = NEW(assign_node); - AS_EX((yyval))->assign->ident = (yyvsp[-2]); - MAKE_REF_BINOP(AS_EX((yyval))->assign->value, OP_SUB, (yyvsp[-2]), (yyvsp[0])); + AS_EX((yyval))->assign->ident = (yyvsp[(1) - (3)]); + MAKE_REF_BINOP(AS_EX((yyval))->assign->value, OP_SUB, (yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])); } -#line 1737 "parser.tab.c" /* yacc.c:1646 */ break; case 18: -#line 86 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 86 "parser.y" { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_ASSIGN; AS_EX((yyval))->assign = NEW(assign_node); - AS_EX((yyval))->assign->ident = (yyvsp[-2]); - MAKE_REF_BINOP(AS_EX((yyval))->assign->value, OP_MUL, (yyvsp[-2]), (yyvsp[0])); + AS_EX((yyval))->assign->ident = (yyvsp[(1) - (3)]); + MAKE_REF_BINOP(AS_EX((yyval))->assign->value, OP_MUL, (yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])); } -#line 1749 "parser.tab.c" /* yacc.c:1646 */ break; case 19: -#line 93 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 93 "parser.y" { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_ASSIGN; AS_EX((yyval))->assign = NEW(assign_node); - AS_EX((yyval))->assign->ident = (yyvsp[-2]); - MAKE_REF_BINOP(AS_EX((yyval))->assign->value, OP_DIV, (yyvsp[-2]), (yyvsp[0])); + AS_EX((yyval))->assign->ident = (yyvsp[(1) - (3)]); + MAKE_REF_BINOP(AS_EX((yyval))->assign->value, OP_DIV, (yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])); } -#line 1761 "parser.tab.c" /* yacc.c:1646 */ break; case 20: -#line 100 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 100 "parser.y" { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_ASSIGN; AS_EX((yyval))->assign = NEW(assign_node); - AS_EX((yyval))->assign->ident = (yyvsp[-2]); - MAKE_REF_BINOP(AS_EX((yyval))->assign->value, OP_POW, (yyvsp[-2]), (yyvsp[0])); + AS_EX((yyval))->assign->ident = (yyvsp[(1) - (3)]); + MAKE_REF_BINOP(AS_EX((yyval))->assign->value, OP_POW, (yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])); } -#line 1773 "parser.tab.c" /* yacc.c:1646 */ break; case 21: -#line 107 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 107 "parser.y" { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_ASSIGN; AS_EX((yyval))->assign = NEW(assign_node); - AS_EX((yyval))->assign->ident = (yyvsp[-2]); - MAKE_REF_BINOP(AS_EX((yyval))->assign->value, OP_BAND, (yyvsp[-2]), (yyvsp[0])); + AS_EX((yyval))->assign->ident = (yyvsp[(1) - (3)]); + MAKE_REF_BINOP(AS_EX((yyval))->assign->value, OP_BAND, (yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])); } -#line 1785 "parser.tab.c" /* yacc.c:1646 */ break; case 22: -#line 114 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 114 "parser.y" { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_ASSIGN; AS_EX((yyval))->assign = NEW(assign_node); - AS_EX((yyval))->assign->ident = (yyvsp[-2]); - MAKE_REF_BINOP(AS_EX((yyval))->assign->value, OP_BOR, (yyvsp[-2]), (yyvsp[0])); + AS_EX((yyval))->assign->ident = (yyvsp[(1) - (3)]); + MAKE_REF_BINOP(AS_EX((yyval))->assign->value, OP_BOR, (yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])); } -#line 1797 "parser.tab.c" /* yacc.c:1646 */ break; case 23: -#line 121 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 121 "parser.y" { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_ASSIGN; AS_EX((yyval))->assign = NEW(assign_node); - AS_EX((yyval))->assign->ident = (yyvsp[-2]); - MAKE_REF_BINOP(AS_EX((yyval))->assign->value, OP_BXOR, (yyvsp[-2]), (yyvsp[0])); + AS_EX((yyval))->assign->ident = (yyvsp[(1) - (3)]); + MAKE_REF_BINOP(AS_EX((yyval))->assign->value, OP_BXOR, (yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])); } -#line 1809 "parser.tab.c" /* yacc.c:1646 */ break; case 24: -#line 128 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 128 "parser.y" { - if(AS_EX((yyvsp[-2]))->type != EX_INDEX) { + if(AS_EX((yyvsp[(1) - (3)]))->type != EX_INDEX) { yyerror("Assigning to non-indexing expression"); YYABORT; } (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_SETINDEX; AS_EX((yyval))->setindex = NEW(setindex_node); - AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr; - AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index; - AS_EX((yyval))->setindex->value = (yyvsp[0]); + AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[(1) - (3)]))->index->expr; + AS_EX((yyval))->setindex->index = AS_EX((yyvsp[(1) - (3)]))->index->index; + AS_EX((yyval))->setindex->value = (yyvsp[(3) - (3)]); //ex_free(AS_EX($1)); } -#line 1827 "parser.tab.c" /* yacc.c:1646 */ break; case 25: -#line 141 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 141 "parser.y" { - if(AS_EX((yyvsp[-2]))->type != EX_INDEX) { + if(AS_EX((yyvsp[(1) - (3)]))->type != EX_INDEX) { yyerror("Assigning to non-indexing expression"); YYABORT; } (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_SETINDEX; AS_EX((yyval))->setindex = NEW(setindex_node); - AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr; - AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index; - MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_ADD, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0])); + AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[(1) - (3)]))->index->expr; + AS_EX((yyval))->setindex->index = AS_EX((yyvsp[(1) - (3)]))->index->index; + MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_ADD, AS_EX((yyvsp[(1) - (3)]))->index->expr, AS_EX((yyvsp[(1) - (3)]))->index->index, (yyvsp[(3) - (3)])); //ex_free(AS_EX($1)); } -#line 1845 "parser.tab.c" /* yacc.c:1646 */ break; case 26: -#line 154 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 154 "parser.y" { - if(AS_EX((yyvsp[-2]))->type != EX_INDEX) { + if(AS_EX((yyvsp[(1) - (3)]))->type != EX_INDEX) { yyerror("Assigning to non-indexing expression"); YYABORT; } (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_SETINDEX; AS_EX((yyval))->setindex = NEW(setindex_node); - AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr; - AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index; - MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_SUB, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0])); + AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[(1) - (3)]))->index->expr; + AS_EX((yyval))->setindex->index = AS_EX((yyvsp[(1) - (3)]))->index->index; + MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_SUB, AS_EX((yyvsp[(1) - (3)]))->index->expr, AS_EX((yyvsp[(1) - (3)]))->index->index, (yyvsp[(3) - (3)])); //ex_free(AS_EX($1)); } -#line 1863 "parser.tab.c" /* yacc.c:1646 */ break; case 27: -#line 167 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 167 "parser.y" { - if(AS_EX((yyvsp[-2]))->type != EX_INDEX) { + if(AS_EX((yyvsp[(1) - (3)]))->type != EX_INDEX) { yyerror("Assigning to non-indexing expression"); YYABORT; } (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_SETINDEX; AS_EX((yyval))->setindex = NEW(setindex_node); - AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr; - AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index; - MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_MUL, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0])); + AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[(1) - (3)]))->index->expr; + AS_EX((yyval))->setindex->index = AS_EX((yyvsp[(1) - (3)]))->index->index; + MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_MUL, AS_EX((yyvsp[(1) - (3)]))->index->expr, AS_EX((yyvsp[(1) - (3)]))->index->index, (yyvsp[(3) - (3)])); //ex_free(AS_EX($1)); } -#line 1881 "parser.tab.c" /* yacc.c:1646 */ break; case 28: -#line 180 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 180 "parser.y" { - if(AS_EX((yyvsp[-2]))->type != EX_INDEX) { + if(AS_EX((yyvsp[(1) - (3)]))->type != EX_INDEX) { yyerror("Assigning to non-indexing expression"); YYABORT; } (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_SETINDEX; AS_EX((yyval))->setindex = NEW(setindex_node); - AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr; - AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index; - MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_DIV, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0])); + AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[(1) - (3)]))->index->expr; + AS_EX((yyval))->setindex->index = AS_EX((yyvsp[(1) - (3)]))->index->index; + MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_DIV, AS_EX((yyvsp[(1) - (3)]))->index->expr, AS_EX((yyvsp[(1) - (3)]))->index->index, (yyvsp[(3) - (3)])); //ex_free(AS_EX($1)); } -#line 1899 "parser.tab.c" /* yacc.c:1646 */ break; case 29: -#line 193 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 193 "parser.y" { - if(AS_EX((yyvsp[-2]))->type != EX_INDEX) { + if(AS_EX((yyvsp[(1) - (3)]))->type != EX_INDEX) { yyerror("Assigning to non-indexing expression"); YYABORT; } (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_SETINDEX; AS_EX((yyval))->setindex = NEW(setindex_node); - AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr; - AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index; - MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_POW, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0])); + AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[(1) - (3)]))->index->expr; + AS_EX((yyval))->setindex->index = AS_EX((yyvsp[(1) - (3)]))->index->index; + MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_POW, AS_EX((yyvsp[(1) - (3)]))->index->expr, AS_EX((yyvsp[(1) - (3)]))->index->index, (yyvsp[(3) - (3)])); //ex_free(AS_EX($1)); } -#line 1917 "parser.tab.c" /* yacc.c:1646 */ break; case 30: -#line 206 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 206 "parser.y" { - if(AS_EX((yyvsp[-2]))->type != EX_INDEX) { + if(AS_EX((yyvsp[(1) - (3)]))->type != EX_INDEX) { yyerror("Assigning to non-indexing expression"); YYABORT; } (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_SETINDEX; AS_EX((yyval))->setindex = NEW(setindex_node); - AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr; - AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index; - MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_BAND, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0])); + AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[(1) - (3)]))->index->expr; + AS_EX((yyval))->setindex->index = AS_EX((yyvsp[(1) - (3)]))->index->index; + MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_BAND, AS_EX((yyvsp[(1) - (3)]))->index->expr, AS_EX((yyvsp[(1) - (3)]))->index->index, (yyvsp[(3) - (3)])); //ex_free(AS_EX($1)); } -#line 1935 "parser.tab.c" /* yacc.c:1646 */ break; case 31: -#line 219 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 219 "parser.y" { - if(AS_EX((yyvsp[-2]))->type != EX_INDEX) { + if(AS_EX((yyvsp[(1) - (3)]))->type != EX_INDEX) { yyerror("Assigning to non-indexing expression"); YYABORT; } (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_SETINDEX; AS_EX((yyval))->setindex = NEW(setindex_node); - AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr; - AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index; - MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_BOR, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0])); + AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[(1) - (3)]))->index->expr; + AS_EX((yyval))->setindex->index = AS_EX((yyvsp[(1) - (3)]))->index->index; + MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_BOR, AS_EX((yyvsp[(1) - (3)]))->index->expr, AS_EX((yyvsp[(1) - (3)]))->index->index, (yyvsp[(3) - (3)])); //ex_free(AS_EX($1)); } -#line 1953 "parser.tab.c" /* yacc.c:1646 */ break; case 32: -#line 232 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 232 "parser.y" { - if(AS_EX((yyvsp[-2]))->type != EX_INDEX) { + if(AS_EX((yyvsp[(1) - (3)]))->type != EX_INDEX) { yyerror("Assigning to non-indexing expression"); YYABORT; } (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_SETINDEX; AS_EX((yyval))->setindex = NEW(setindex_node); - AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr; - AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index; - MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_BXOR, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0])); + AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[(1) - (3)]))->index->expr; + AS_EX((yyval))->setindex->index = AS_EX((yyvsp[(1) - (3)]))->index->index; + MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_BXOR, AS_EX((yyvsp[(1) - (3)]))->index->expr, AS_EX((yyvsp[(1) - (3)]))->index->index, (yyvsp[(3) - (3)])); //ex_free(AS_EX($1)); } -#line 1971 "parser.tab.c" /* yacc.c:1646 */ break; case 33: -#line 245 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]); } -#line 1977 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 245 "parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 34: -#line 249 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_LAND; AS_EX((yyval))->binop->left = (yyvsp[-2]); AS_EX((yyval))->binop->right = (yyvsp[0]); } -#line 1983 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 249 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_LAND; AS_EX((yyval))->binop->left = (yyvsp[(1) - (3)]); AS_EX((yyval))->binop->right = (yyvsp[(3) - (3)]); } break; case 35: -#line 250 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_LOR; AS_EX((yyval))->binop->left = (yyvsp[-2]); AS_EX((yyval))->binop->right = (yyvsp[0]); } -#line 1989 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 250 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_LOR; AS_EX((yyval))->binop->left = (yyvsp[(1) - (3)]); AS_EX((yyval))->binop->right = (yyvsp[(3) - (3)]); } break; case 36: -#line 251 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]); } -#line 1995 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 251 "parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 37: -#line 255 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_UNOP; AS_EX((yyval))->unop = NEW(unop_node); AS_EX((yyval))->unop->type = OP_LNOT; AS_EX((yyval))->unop->expr = (yyvsp[0]); } -#line 2001 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 255 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_UNOP; AS_EX((yyval))->unop = NEW(unop_node); AS_EX((yyval))->unop->type = OP_LNOT; AS_EX((yyval))->unop->expr = (yyvsp[(2) - (2)]); } break; case 38: -#line 256 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]); } -#line 2007 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 256 "parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 39: -#line 260 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_EQUAL; AS_EX((yyval))->binop->left = (yyvsp[-2]); AS_EX((yyval))->binop->right = (yyvsp[0]); } -#line 2013 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 260 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_EQUAL; AS_EX((yyval))->binop->left = (yyvsp[(1) - (3)]); AS_EX((yyval))->binop->right = (yyvsp[(3) - (3)]); } break; case 40: -#line 261 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_LESS; AS_EX((yyval))->binop->left = (yyvsp[-2]); AS_EX((yyval))->binop->right = (yyvsp[0]); } -#line 2019 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 261 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_LESS; AS_EX((yyval))->binop->left = (yyvsp[(1) - (3)]); AS_EX((yyval))->binop->right = (yyvsp[(3) - (3)]); } break; case 41: -#line 262 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_GREATER; AS_EX((yyval))->binop->left = (yyvsp[-2]); AS_EX((yyval))->binop->right = (yyvsp[0]); } -#line 2025 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 262 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_GREATER; AS_EX((yyval))->binop->left = (yyvsp[(1) - (3)]); AS_EX((yyval))->binop->right = (yyvsp[(3) - (3)]); } break; case 42: -#line 263 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_LESSEQ; AS_EX((yyval))->binop->left = (yyvsp[-2]); AS_EX((yyval))->binop->right = (yyvsp[0]); } -#line 2031 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 263 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_LESSEQ; AS_EX((yyval))->binop->left = (yyvsp[(1) - (3)]); AS_EX((yyval))->binop->right = (yyvsp[(3) - (3)]); } break; case 43: -#line 264 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_GREATEREQ; AS_EX((yyval))->binop->left = (yyvsp[-2]); AS_EX((yyval))->binop->right = (yyvsp[0]); } -#line 2037 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 264 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_GREATEREQ; AS_EX((yyval))->binop->left = (yyvsp[(1) - (3)]); AS_EX((yyval))->binop->right = (yyvsp[(3) - (3)]); } break; case 44: -#line 265 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]); } -#line 2043 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 265 "parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 45: -#line 269 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_ADD; AS_EX((yyval))->binop->left = (yyvsp[-2]); AS_EX((yyval))->binop->right = (yyvsp[0]); } -#line 2049 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 269 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_ADD; AS_EX((yyval))->binop->left = (yyvsp[(1) - (3)]); AS_EX((yyval))->binop->right = (yyvsp[(3) - (3)]); } break; case 46: -#line 270 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_SUB; AS_EX((yyval))->binop->left = (yyvsp[-2]); AS_EX((yyval))->binop->right = (yyvsp[0]); } -#line 2055 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 270 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_SUB; AS_EX((yyval))->binop->left = (yyvsp[(1) - (3)]); AS_EX((yyval))->binop->right = (yyvsp[(3) - (3)]); } break; case 47: -#line 271 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]); } -#line 2061 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 271 "parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 48: -#line 275 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_MUL; AS_EX((yyval))->binop->left = (yyvsp[-2]); AS_EX((yyval))->binop->right = (yyvsp[0]); } -#line 2067 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 275 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_MUL; AS_EX((yyval))->binop->left = (yyvsp[(1) - (3)]); AS_EX((yyval))->binop->right = (yyvsp[(3) - (3)]); } break; case 49: -#line 276 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_DIV; AS_EX((yyval))->binop->left = (yyvsp[-2]); AS_EX((yyval))->binop->right = (yyvsp[0]); } -#line 2073 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 276 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_DIV; AS_EX((yyval))->binop->left = (yyvsp[(1) - (3)]); AS_EX((yyval))->binop->right = (yyvsp[(3) - (3)]); } break; case 50: -#line 277 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_MOD; AS_EX((yyval))->binop->left = (yyvsp[-2]); AS_EX((yyval))->binop->right = (yyvsp[0]); } -#line 2079 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 277 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_MOD; AS_EX((yyval))->binop->left = (yyvsp[(1) - (3)]); AS_EX((yyval))->binop->right = (yyvsp[(3) - (3)]); } break; case 51: -#line 278 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]); } -#line 2085 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 278 "parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 52: -#line 282 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_POW; AS_EX((yyval))->binop->left = (yyvsp[-2]); AS_EX((yyval))->binop->right = (yyvsp[0]); } -#line 2091 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 282 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_POW; AS_EX((yyval))->binop->left = (yyvsp[(1) - (3)]); AS_EX((yyval))->binop->right = (yyvsp[(3) - (3)]); } break; case 53: -#line 283 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]); } -#line 2097 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 283 "parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 54: -#line 287 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_BAND; AS_EX((yyval))->binop->left = (yyvsp[-2]); AS_EX((yyval))->binop->right = (yyvsp[0]); } -#line 2103 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 287 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_BAND; AS_EX((yyval))->binop->left = (yyvsp[(1) - (3)]); AS_EX((yyval))->binop->right = (yyvsp[(3) - (3)]); } break; case 55: -#line 288 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_BOR; AS_EX((yyval))->binop->left = (yyvsp[-2]); AS_EX((yyval))->binop->right = (yyvsp[0]); } -#line 2109 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 288 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_BOR; AS_EX((yyval))->binop->left = (yyvsp[(1) - (3)]); AS_EX((yyval))->binop->right = (yyvsp[(3) - (3)]); } break; case 56: -#line 289 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_BXOR; AS_EX((yyval))->binop->left = (yyvsp[-2]); AS_EX((yyval))->binop->right = (yyvsp[0]); } -#line 2115 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 289 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_BXOR; AS_EX((yyval))->binop->left = (yyvsp[(1) - (3)]); AS_EX((yyval))->binop->right = (yyvsp[(3) - (3)]); } break; case 57: -#line 290 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_LSHIFT; AS_EX((yyval))->binop->left = (yyvsp[-2]); AS_EX((yyval))->binop->right = (yyvsp[0]); } -#line 2121 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 290 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_LSHIFT; AS_EX((yyval))->binop->left = (yyvsp[(1) - (3)]); AS_EX((yyval))->binop->right = (yyvsp[(3) - (3)]); } break; case 58: -#line 291 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_RSHIFT; AS_EX((yyval))->binop->left = (yyvsp[-2]); AS_EX((yyval))->binop->right = (yyvsp[0]); } -#line 2127 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 291 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_BINOP; AS_EX((yyval))->binop = NEW(binop_node); AS_EX((yyval))->binop->type = OP_RSHIFT; AS_EX((yyval))->binop->left = (yyvsp[(1) - (3)]); AS_EX((yyval))->binop->right = (yyvsp[(3) - (3)]); } break; case 59: -#line 292 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]); } -#line 2133 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 292 "parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 60: -#line 296 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_UNOP; AS_EX((yyval))->unop = NEW(unop_node); AS_EX((yyval))->unop->type = OP_BNOT; AS_EX((yyval))->unop->expr = (yyvsp[0]); } -#line 2139 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 296 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_UNOP; AS_EX((yyval))->unop = NEW(unop_node); AS_EX((yyval))->unop->type = OP_BNOT; AS_EX((yyval))->unop->expr = (yyvsp[(2) - (2)]); } break; case 61: -#line 297 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]); } -#line 2145 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 297 "parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 62: -#line 301 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_UNOP; AS_EX((yyval))->unop = NEW(unop_node); AS_EX((yyval))->unop->type = OP_LEN; AS_EX((yyval))->unop->expr = (yyvsp[0]); } -#line 2151 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 301 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_UNOP; AS_EX((yyval))->unop = NEW(unop_node); AS_EX((yyval))->unop->type = OP_LEN; AS_EX((yyval))->unop->expr = (yyvsp[(2) - (2)]); } break; case 63: -#line 302 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]); } -#line 2157 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 302 "parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 64: -#line 306 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_CALL; AS_EX((yyval))->call = NEW(call_node); AS_EX((yyval))->call->expr = (yyvsp[-3]); AS_EX((yyval))->call->args = (yyvsp[-1]); } -#line 2163 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 306 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_CALL; AS_EX((yyval))->call = NEW(call_node); AS_EX((yyval))->call->expr = (yyvsp[(1) - (4)]); AS_EX((yyval))->call->args = (yyvsp[(3) - (4)]); } break; case 65: -#line 307 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 307 "parser.y" { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_CALL; @@ -2171,313 +2368,313 @@ yyreduce: AS_EX((yyval))->call->expr = NEW_EX(); AS_EX((yyval))->call->expr->type = EX_INDEX; AS_EX((yyval))->call->expr->index = NEW(index_node); - AS_EX((yyval))->call->expr->index->expr = (yyvsp[-5]); + AS_EX((yyval))->call->expr->index->expr = (yyvsp[(1) - (6)]); AS_EX((yyval))->call->expr->index->index = NEW_EX(); AS_EX((yyval))->call->expr->index->index->type = EX_LIT; AS_EX((yyval))->call->expr->index->index->lit = NEW(lit_node); AS_EX((yyval))->call->expr->index->index->lit->type = LIT_STRING; - AS_EX((yyval))->call->expr->index->index->lit->str = (yyvsp[-3]); + AS_EX((yyval))->call->expr->index->index->lit->str = (yyvsp[(3) - (6)]); AS_EX((yyval))->call->args = NEW(exprlist_node); - AS_EX((yyval))->call->args->expr = (yyvsp[-5]); - AS_EX((yyval))->call->args->next = (yyvsp[-1]); + AS_EX((yyval))->call->args->expr = (yyvsp[(1) - (6)]); + AS_EX((yyval))->call->args->next = (yyvsp[(5) - (6)]); } -#line 2185 "parser.tab.c" /* yacc.c:1646 */ break; case 66: -#line 324 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]); } -#line 2191 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 324 "parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 67: -#line 328 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 328 "parser.y" { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_FUNCDECL; AS_EX((yyval))->funcdecl = NEW(funcdecl_node); - AS_EX((yyval))->funcdecl->name = (yyvsp[-5]); - AS_EX((yyval))->funcdecl->args = (yyvsp[-3]); - AS_EX((yyval))->funcdecl->body = (yyvsp[-1]); + AS_EX((yyval))->funcdecl->name = (yyvsp[(2) - (7)]); + AS_EX((yyval))->funcdecl->args = (yyvsp[(4) - (7)]); + AS_EX((yyval))->funcdecl->body = (yyvsp[(6) - (7)]); } -#line 2204 "parser.tab.c" /* yacc.c:1646 */ break; case 68: -#line 336 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 336 "parser.y" { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_FUNCDECL; AS_EX((yyval))->funcdecl = NEW(funcdecl_node); AS_EX((yyval))->funcdecl->name = NULL; - AS_EX((yyval))->funcdecl->args = (yyvsp[-3]); - AS_EX((yyval))->funcdecl->body = (yyvsp[-1]); + AS_EX((yyval))->funcdecl->args = (yyvsp[(3) - (6)]); + AS_EX((yyval))->funcdecl->body = (yyvsp[(5) - (6)]); } -#line 2217 "parser.tab.c" /* yacc.c:1646 */ break; case 69: -#line 344 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]); } -#line 2223 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 344 "parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 70: -#line 348 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_INDEX; AS_EX((yyval))->index = NEW(index_node); AS_EX((yyval))->index->expr = (yyvsp[-3]); AS_EX((yyval))->index->index = (yyvsp[-1]); } -#line 2229 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 348 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_INDEX; AS_EX((yyval))->index = NEW(index_node); AS_EX((yyval))->index->expr = (yyvsp[(1) - (4)]); AS_EX((yyval))->index->index = (yyvsp[(3) - (4)]); } break; case 71: -#line 349 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 349 "parser.y" { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_INDEX; AS_EX((yyval))->index = NEW(index_node); - AS_EX((yyval))->index->expr = (yyvsp[-2]); + AS_EX((yyval))->index->expr = (yyvsp[(1) - (3)]); AS_EX((yyval))->index->index = NEW_EX(); AS_EX((yyval))->index->index->type = EX_LIT; AS_EX((yyval))->index->index->lit = NEW(lit_node); AS_EX((yyval))->index->index->lit->type = LIT_STRING; - AS_EX((yyval))->index->index->lit->str = (yyvsp[0]); + AS_EX((yyval))->index->index->lit->str = (yyvsp[(3) - (3)]); } -#line 2245 "parser.tab.c" /* yacc.c:1646 */ break; case 72: -#line 360 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]); } -#line 2251 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 360 "parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 73: -#line 364 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_INDEX; AS_EX((yyval))->index = NEW(index_node); AS_EX((yyval))->index->expr = (yyvsp[-3]); AS_EX((yyval))->index->index = (yyvsp[-1]); } -#line 2257 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 364 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_INDEX; AS_EX((yyval))->index = NEW(index_node); AS_EX((yyval))->index->expr = (yyvsp[(1) - (4)]); AS_EX((yyval))->index->index = (yyvsp[(3) - (4)]); } break; case 74: -#line 365 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 365 "parser.y" { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_INDEX; AS_EX((yyval))->index = NEW(index_node); - AS_EX((yyval))->index->expr = (yyvsp[-2]); + AS_EX((yyval))->index->expr = (yyvsp[(1) - (3)]); AS_EX((yyval))->index->index = NEW_EX(); AS_EX((yyval))->index->index->type = EX_LIT; AS_EX((yyval))->index->index->lit = NEW(lit_node); AS_EX((yyval))->index->index->lit->type = LIT_STRING; - AS_EX((yyval))->index->index->lit->str = (yyvsp[0]); + AS_EX((yyval))->index->index->lit->str = (yyvsp[(3) - (3)]); } -#line 2273 "parser.tab.c" /* yacc.c:1646 */ break; case 75: -#line 379 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_REF; AS_EX((yyval))->ref = NEW(ref_node); AS_EX((yyval))->ref->ident = (yyvsp[0]); } -#line 2279 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 379 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_REF; AS_EX((yyval))->ref = NEW(ref_node); AS_EX((yyval))->ref->ident = (yyvsp[(1) - (1)]); } break; case 76: -#line 380 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]); } -#line 2285 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 380 "parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 77: -#line 384 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_LIT; AS_EX((yyval))->lit = NEW(lit_node); AS_EX((yyval))->lit->type = LIT_INT; AS_EX((yyval))->lit->ival = *AS((yyvsp[0]), long); free((yyvsp[0])); } -#line 2291 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 384 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_LIT; AS_EX((yyval))->lit = NEW(lit_node); AS_EX((yyval))->lit->type = LIT_INT; AS_EX((yyval))->lit->ival = *AS((yyvsp[(1) - (1)]), long); free((yyvsp[(1) - (1)])); } break; case 78: -#line 385 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_LIT; AS_EX((yyval))->lit = NEW(lit_node); AS_EX((yyval))->lit->type = LIT_INT; AS_EX((yyval))->lit->ival = -(*AS((yyvsp[0]), long)); free((yyvsp[0])); } -#line 2297 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 385 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_LIT; AS_EX((yyval))->lit = NEW(lit_node); AS_EX((yyval))->lit->type = LIT_INT; AS_EX((yyval))->lit->ival = -(*AS((yyvsp[(2) - (2)]), long)); free((yyvsp[(2) - (2)])); } break; case 79: -#line 386 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_LIT; AS_EX((yyval))->lit = NEW(lit_node); AS_EX((yyval))->lit->type = LIT_FLOAT; AS_EX((yyval))->lit->fval = *AS((yyvsp[0]), double); free((yyvsp[0])); } -#line 2303 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 386 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_LIT; AS_EX((yyval))->lit = NEW(lit_node); AS_EX((yyval))->lit->type = LIT_FLOAT; AS_EX((yyval))->lit->fval = *AS((yyvsp[(1) - (1)]), double); free((yyvsp[(1) - (1)])); } break; case 80: -#line 387 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_LIT; AS_EX((yyval))->lit = NEW(lit_node); AS_EX((yyval))->lit->type = LIT_STRING; AS_EX((yyval))->lit->str = (yyvsp[0]); } -#line 2309 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 387 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_LIT; AS_EX((yyval))->lit = NEW(lit_node); AS_EX((yyval))->lit->type = LIT_STRING; AS_EX((yyval))->lit->str = (yyvsp[(1) - (1)]); } break; case 81: -#line 388 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 388 "parser.y" { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_LIT; AS_EX((yyval))->lit = NEW(lit_node); AS_EX((yyval))->lit->type = LIT_NONE; } -#line 2315 "parser.tab.c" /* yacc.c:1646 */ break; case 82: -#line 389 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]); } -#line 2321 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 389 "parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 83: -#line 393 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_LISTGEN; AS_EX((yyval))->listgen = NEW(listgen_node); AS_EX((yyval))->listgen->list = (yyvsp[-1]); } -#line 2327 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 393 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_LISTGEN; AS_EX((yyval))->listgen = NEW(listgen_node); AS_EX((yyval))->listgen->list = (yyvsp[(2) - (3)]); } break; case 84: -#line 394 "parser.y" /* yacc.c:1646 */ - { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_MAPGEN; AS_EX((yyval))->mapgen = NEW(mapgen_node); AS_EX((yyval))->mapgen->map = (yyvsp[-1]); } -#line 2333 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 394 "parser.y" + { (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_MAPGEN; AS_EX((yyval))->mapgen = NEW(mapgen_node); AS_EX((yyval))->mapgen->map = (yyvsp[(2) - (3)]); } break; case 85: -#line 395 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]); } -#line 2339 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 395 "parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 86: -#line 399 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[-1]); } -#line 2345 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 399 "parser.y" + { (yyval) = (yyvsp[(2) - (3)]); } break; case 87: -#line 403 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 403 "parser.y" { (yyval) = NULL; } -#line 2351 "parser.tab.c" /* yacc.c:1646 */ break; case 88: -#line 404 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 404 "parser.y" { (yyval) = NEW(exprlist_node); - AS((yyval), exprlist_node)->expr = (yyvsp[0]); + AS((yyval), exprlist_node)->expr = (yyvsp[(1) - (1)]); AS((yyval), exprlist_node)->next = NULL; } -#line 2361 "parser.tab.c" /* yacc.c:1646 */ break; case 89: -#line 409 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[-1]); } -#line 2367 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 409 "parser.y" + { (yyval) = (yyvsp[(1) - (2)]); } break; case 90: -#line 410 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 410 "parser.y" { - exprlist_node *cur = (yyvsp[-1]); + exprlist_node *cur = (yyvsp[(1) - (2)]); while(cur->next) cur = cur->next; cur->next = NEW(exprlist_node); cur = cur->next; - cur->expr = (yyvsp[0]); + cur->expr = (yyvsp[(2) - (2)]); cur->next = NULL; - (yyval) = (yyvsp[-1]); + (yyval) = (yyvsp[(1) - (2)]); } -#line 2381 "parser.tab.c" /* yacc.c:1646 */ break; case 91: -#line 422 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 422 "parser.y" { (yyval) = NULL; } -#line 2387 "parser.tab.c" /* yacc.c:1646 */ break; case 92: -#line 423 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 423 "parser.y" { (yyval) = NEW(identlist_node); - AS((yyval), identlist_node)->ident = (yyvsp[0]); + AS((yyval), identlist_node)->ident = (yyvsp[(1) - (1)]); AS((yyval), identlist_node)->next = NULL; } -#line 2397 "parser.tab.c" /* yacc.c:1646 */ break; case 93: -#line 428 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[-1]); } -#line 2403 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 428 "parser.y" + { (yyval) = (yyvsp[(1) - (2)]); } break; case 94: -#line 429 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 429 "parser.y" { - identlist_node *cur = (yyvsp[-1]); + identlist_node *cur = (yyvsp[(1) - (2)]); while(cur->next) cur = cur->next; cur->next = NEW(identlist_node); cur = cur->next; - cur->ident = (yyvsp[0]); + cur->ident = (yyvsp[(2) - (2)]); cur->next = NULL; - (yyval) = (yyvsp[-1]); + (yyval) = (yyvsp[(1) - (2)]); } -#line 2417 "parser.tab.c" /* yacc.c:1646 */ break; case 95: -#line 441 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 441 "parser.y" { (yyval) = NULL; } -#line 2423 "parser.tab.c" /* yacc.c:1646 */ break; case 96: -#line 442 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 442 "parser.y" { (yyval) = NEW(assoclist_node); - AS((yyval), assoclist_node)->item = (yyvsp[0]); + AS((yyval), assoclist_node)->item = (yyvsp[(1) - (1)]); AS((yyval), assoclist_node)->next = NULL; } -#line 2433 "parser.tab.c" /* yacc.c:1646 */ break; case 97: -#line 447 "parser.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[-1]); } -#line 2439 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 447 "parser.y" + { (yyval) = (yyvsp[(1) - (2)]); } break; case 98: -#line 448 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 448 "parser.y" { - assoclist_node *cur = (yyvsp[-1]); + assoclist_node *cur = (yyvsp[(1) - (2)]); while(cur->next) cur = cur->next; cur->next = NEW(assoclist_node); cur = cur->next; - cur->item = (yyvsp[0]); + cur->item = (yyvsp[(2) - (2)]); cur->next = NULL; - (yyval) = (yyvsp[-1]); + (yyval) = (yyvsp[(1) - (2)]); } -#line 2453 "parser.tab.c" /* yacc.c:1646 */ break; case 99: -#line 460 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 460 "parser.y" { (yyval) = NEW(associtem_node); - AS((yyval), associtem_node)->key = (yyvsp[-3]); - AS((yyval), associtem_node)->value = (yyvsp[0]); + AS((yyval), associtem_node)->key = (yyvsp[(2) - (5)]); + AS((yyval), associtem_node)->value = (yyvsp[(5) - (5)]); } -#line 2463 "parser.tab.c" /* yacc.c:1646 */ break; case 100: -#line 465 "parser.y" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 465 "parser.y" { (yyval) = NEW(associtem_node); AS((yyval), associtem_node)->key = NEW_EX(); AS((yyval), associtem_node)->key->type = EX_LIT; AS((yyval), associtem_node)->key->lit = NEW(lit_node); AS((yyval), associtem_node)->key->lit->type = LIT_STRING; - AS((yyval), associtem_node)->key->lit->str = (yyvsp[-2]); - AS((yyval), associtem_node)->value = (yyvsp[0]); + AS((yyval), associtem_node)->key->lit->str = (yyvsp[(1) - (3)]); + AS((yyval), associtem_node)->value = (yyvsp[(3) - (3)]); } -#line 2477 "parser.tab.c" /* yacc.c:1646 */ break; -#line 2481 "parser.tab.c" /* yacc.c:1646 */ +/* Line 1787 of yacc.c */ +#line 2678 "parser.tab.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -2500,7 +2697,7 @@ yyreduce: *++yyvsp = yyval; *++yylsp = yyloc; - /* Now 'shift' the result of the reduction. Determine what state + /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ @@ -2515,9 +2712,9 @@ yyreduce: goto yynewstate; -/*--------------------------------------. -| yyerrlab -- here on detecting error. | -`--------------------------------------*/ +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ @@ -2568,20 +2765,20 @@ yyerrlab: if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an - error, discard it. */ + error, discard it. */ if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } else - { - yydestruct ("Error: discarding", - yytoken, &yylval, &yylloc, program); - yychar = YYEMPTY; - } + { + yydestruct ("Error: discarding", + yytoken, &yylval, &yylloc, program); + yychar = YYEMPTY; + } } /* Else will try to reuse lookahead token after shifting the error @@ -2601,7 +2798,7 @@ yyerrorlab: goto yyerrorlab; yyerror_range[1] = yylsp[1-yylen]; - /* Do not reclaim the symbols of the rule whose action triggered + /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; @@ -2614,29 +2811,29 @@ yyerrorlab: | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ + yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) - YYABORT; + YYABORT; yyerror_range[1] = *yylsp; yydestruct ("Error: popping", - yystos[yystate], yyvsp, yylsp, program); + yystos[yystate], yyvsp, yylsp, program); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); @@ -2692,14 +2889,14 @@ yyreturn: yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc, program); } - /* Do not reclaim the symbols of the rule whose action triggered + /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, yylsp, program); + yystos[*yyssp], yyvsp, yylsp, program); YYPOPSTACK (1); } #ifndef yyoverflow @@ -2710,9 +2907,13 @@ yyreturn: if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif - return yyresult; + /* Make sure YYID is used. */ + return YYID (yyresult); } -#line 476 "parser.y" /* yacc.c:1906 */ + + +/* Line 2050 of yacc.c */ +#line 476 "parser.y" // TODO diff --git a/parser.tab.h b/parser.tab.h index c6f9a59..6c4e23e 100644 --- a/parser.tab.h +++ b/parser.tab.h @@ -1,19 +1,19 @@ -/* A Bison parser, made by GNU Bison 3.0.2. */ +/* A Bison parser, made by GNU Bison 2.7.12-4996. */ /* Bison interface for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. - + + Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -26,13 +26,13 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ #ifndef YY_YY_PARSER_TAB_H_INCLUDED # define YY_YY_PARSER_TAB_H_INCLUDED -/* Debug traces. */ +/* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 1 #endif @@ -40,94 +40,106 @@ extern int yydebug; #endif -/* Token type. */ +/* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE - enum yytokentype - { - IF = 258, - THEN = 259, - ELSE = 260, - WHILE = 261, - FOR = 262, - IN = 263, - DO = 264, - FUNC = 265, - RETURN = 266, - BREAK = 267, - CONTINUE = 268, - END = 269, - NONE = 270, - IDENT = 271, - INT = 272, - FLOAT = 273, - STRING = 274, - PLUS = 275, - MINUS = 276, - STAR = 277, - SLASH = 278, - PERCENT = 279, - DSTAR = 280, - BAND = 281, - BOR = 282, - BXOR = 283, - BNOT = 284, - LAND = 285, - LOR = 286, - LNOT = 287, - ASSIGN = 288, - ASSIGNPLUS = 289, - ASSIGNMINUS = 290, - ASSIGNSTAR = 291, - ASSIGNSLASH = 292, - ASSIGNDSTAR = 293, - ASSIGNBAND = 294, - ASSIGNBOR = 295, - ASSIGNBXOR = 296, - EQUAL = 297, - LESS = 298, - GREATER = 299, - LESSEQ = 300, - GREATEREQ = 301, - RSHIFT = 302, - LSHIFT = 303, - LBRACE = 304, - RBRACE = 305, - LPAREN = 306, - RPAREN = 307, - LBRACKET = 308, - RBRACKET = 309, - DOT = 310, - COLON = 311, - SEMICOLON = 312, - COMMA = 313, - POUND = 314 - }; + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + IF = 258, + THEN = 259, + ELSE = 260, + WHILE = 261, + FOR = 262, + IN = 263, + DO = 264, + FUNC = 265, + RETURN = 266, + BREAK = 267, + CONTINUE = 268, + END = 269, + NONE = 270, + IDENT = 271, + INT = 272, + FLOAT = 273, + STRING = 274, + PLUS = 275, + MINUS = 276, + STAR = 277, + SLASH = 278, + PERCENT = 279, + DSTAR = 280, + BAND = 281, + BOR = 282, + BXOR = 283, + BNOT = 284, + LAND = 285, + LOR = 286, + LNOT = 287, + ASSIGN = 288, + ASSIGNPLUS = 289, + ASSIGNMINUS = 290, + ASSIGNSTAR = 291, + ASSIGNSLASH = 292, + ASSIGNDSTAR = 293, + ASSIGNBAND = 294, + ASSIGNBOR = 295, + ASSIGNBXOR = 296, + EQUAL = 297, + LESS = 298, + GREATER = 299, + LESSEQ = 300, + GREATEREQ = 301, + RSHIFT = 302, + LSHIFT = 303, + LBRACE = 304, + RBRACE = 305, + LPAREN = 306, + RPAREN = 307, + LBRACKET = 308, + RBRACKET = 309, + DOT = 310, + COLON = 311, + SEMICOLON = 312, + COMMA = 313, + POUND = 314 + }; #endif -/* Value type. */ + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef int YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 #endif -/* Location type. */ #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE YYLTYPE; -struct YYLTYPE +typedef struct YYLTYPE { int first_line; int first_column; int last_line; int last_column; -}; +} YYLTYPE; +# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ # define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_TRIVIAL 1 #endif - +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus int yyparse (stmt_node **program); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ #endif /* !YY_YY_PARSER_TAB_H_INCLUDED */ diff --git a/parser.y b/parser.y index f2ce554..54d8082 100644 --- a/parser.y +++ b/parser.y @@ -55,15 +55,15 @@ stmt_list: ; stmt: - expr { $$ = NEW_ST(); AS_ST($$)->type = ST_EXPR; AS_ST($$)->expr = $1; } -| IF expr THEN stmt_list END { $$ = NEW_ST(); AS_ST($$)->type = ST_IFELSE; AS_ST($$)->ifelse = NEW(ifelse_node); AS_ST($$)->ifelse->cond = $2; AS_ST($$)->ifelse->iftrue = $4; AS_ST($$)->ifelse->iffalse = NULL; } -| IF expr THEN stmt_list ELSE stmt_list END { $$ = NEW_ST(); AS_ST($$)->type = ST_IFELSE; AS_ST($$)->ifelse = NEW(ifelse_node); AS_ST($$)->ifelse->cond = $2; AS_ST($$)->ifelse->iftrue = $4; AS_ST($$)->ifelse->iffalse = $6; } -| WHILE expr DO stmt_list END { $$ = NEW_ST(); AS_ST($$)->type = ST_LOOP; AS_ST($$)->loop = NEW(loop_node); AS_ST($$)->loop->cond = $2; AS_ST($$)->loop->loop = $4; } -| FOR IDENT IN expr DO stmt_list END { $$ = NEW_ST(); AS_ST($$)->type = ST_ITER; AS_ST($$)->iter = NEW(iter_node); AS_ST($$)->iter->var = $2; AS_ST($$)->iter->iter = $4; AS_ST($$)->iter->loop = $6; } -| RETURN expr { $$ = NEW_ST(); AS_ST($$)->type = ST_RET; AS_ST($$)->ret = NEW(ret_node); AS_ST($$)->ret->ret = $2; } -| RETURN { $$ = NEW_ST(); AS_ST($$)->type = ST_RET; AS_ST($$)->ret = NEW(ret_node); AS_ST($$)->ret->ret = NULL; } -| BREAK { $$ = NEW_ST(); AS_ST($$)->type = ST_BREAK; } -| CONTINUE { $$ = NEW_ST(); AS_ST($$)->type = ST_CONT; } + expr { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_EXPR; AS_ST($$)->expr = $1; } +| IF expr THEN stmt_list END { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_IFELSE; AS_ST($$)->ifelse = NEW(ifelse_node); AS_ST($$)->ifelse->cond = $2; AS_ST($$)->ifelse->iftrue = $4; AS_ST($$)->ifelse->iffalse = NULL; } +| IF expr THEN stmt_list ELSE stmt_list END { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_IFELSE; AS_ST($$)->ifelse = NEW(ifelse_node); AS_ST($$)->ifelse->cond = $2; AS_ST($$)->ifelse->iftrue = $4; AS_ST($$)->ifelse->iffalse = $6; } +| WHILE expr DO stmt_list END { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_LOOP; AS_ST($$)->loop = NEW(loop_node); AS_ST($$)->loop->cond = $2; AS_ST($$)->loop->loop = $4; } +| FOR IDENT IN expr DO stmt_list END { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_ITER; AS_ST($$)->iter = NEW(iter_node); AS_ST($$)->iter->var = $2; AS_ST($$)->iter->iter = $4; AS_ST($$)->iter->loop = $6; } +| RETURN expr { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_RET; AS_ST($$)->ret = NEW(ret_node); AS_ST($$)->ret->ret = $2; } +| RETURN { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_RET; AS_ST($$)->ret = NEW(ret_node); AS_ST($$)->ret->ret = NULL; } +| BREAK { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_BREAK; } +| CONTINUE { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_CONT; } | stmt SEMICOLON { $$ = $1; } ; diff --git a/runtime.c b/runtime.c index 8a800dc..8c4280b 100644 --- a/runtime.c +++ b/runtime.c @@ -450,6 +450,9 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) { switch(stmt->type) { case ST_EXPR: sol_obj_free(sol_eval(state, stmt->expr)); + if(sol_has_error(state)) { + sol_add_traceback(state, sol_new_stmtnode(state, stmt)); + } break; case ST_IFELSE: @@ -462,6 +465,9 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) { } sol_obj_free(value); sol_obj_free(vint); + if(sol_has_error(state)) { + sol_add_traceback(state, sol_new_stmtnode(state, stmt)); + } break; case ST_LOOP: @@ -471,11 +477,19 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) { sol_obj_free(value); sol_obj_free(vint); sol_exec(state, stmt->loop->loop); - if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) break; + if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) { + value = sol_incref(state->None); + vint = sol_new_int(state, 0); + continue; + } + state->sflag = SF_NORMAL; value = sol_eval(state, stmt->loop->cond); vint = sol_cast_int(state, value); } state->sflag = SF_NORMAL; + if(sol_has_error(state)) { + sol_add_traceback(state, sol_new_stmtnode(state, stmt)); + } sol_obj_free(value); sol_obj_free(vint); break; @@ -503,13 +517,20 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) { sol_state_assign_l_name(state, stmt->iter->var, item); sol_exec(state, stmt->iter->loop); sol_obj_free(item); - if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) break; + if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) { + item = sol_incref(state->StopIteration); + } + state->sflag = SF_NORMAL; item = iter->ops->call(state, list); } state->sflag = SF_NORMAL; - sol_obj_free(list); + if(sol_has_error(state)) { + sol_add_traceback(state, sol_new_stmtnode(state, stmt)); + } sol_obj_free(iter); sol_obj_free(value); + sol_obj_free(list); + sol_obj_free(item); break; case ST_LIST: @@ -518,6 +539,9 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) { if(curs->stmt) sol_exec(state, curs->stmt); curs = curs->next; } + if(sol_has_error(state)) { + sol_add_traceback(state, sol_new_stmtnode(state, stmt)); + } break; case ST_RET: @@ -526,6 +550,9 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) { } else { state->ret = sol_incref(state->None); } + if(sol_has_error(state)) { + sol_add_traceback(state, sol_new_stmtnode(state, stmt)); + } break; case ST_CONT: @@ -594,7 +621,6 @@ sol_object_t *sol_f_func_call(sol_state_t *state, sol_object_t *args) { sol_object_t *sol_new_func(sol_state_t *state, identlist_node *identlist, stmt_node *body, char *name) { sol_object_t *obj = sol_alloc_object(state); - if(sol_has_error(state)) return sol_incref(state->None); obj->func = body; obj->args = identlist; obj->fname = (name?strdup(name):NULL); @@ -607,7 +633,6 @@ sol_object_t *sol_new_func(sol_state_t *state, identlist_node *identlist, stmt_n sol_object_t *sol_new_stmtnode(sol_state_t *state, stmt_node *stmt) { sol_object_t *obj = sol_alloc_object(state); - if(sol_has_error(state)) return sol_incref(state->None); obj->type = SOL_STMT; obj->ops = &(state->ASTNodeOps); obj->node = stmt; @@ -616,7 +641,6 @@ sol_object_t *sol_new_stmtnode(sol_state_t *state, stmt_node *stmt) { sol_object_t *sol_new_exprnode(sol_state_t *state, expr_node *expr) { sol_object_t *obj = sol_alloc_object(state); - if(sol_has_error(state)) return sol_incref(state->None); obj->type = SOL_EXPR; obj->ops = &(state->ASTNodeOps); obj->node = expr; diff --git a/sol.h b/sol.h index c789fb5..9073b5a 100644 --- a/sol.h +++ b/sol.h @@ -6,6 +6,7 @@ #endif #include +#include #include "dsl/dsl.h" #define VERSION "0.1a0" @@ -156,6 +157,7 @@ typedef enum {SF_NORMAL, SF_BREAKING, SF_CONTINUING} sol_state_flag_t; typedef struct sol_tag_state_t { sol_object_t *scopes; // A list of scope maps, innermost out, ending at the global scope sol_object_t *ret; // Return value of this function, for early return + sol_object_t *traceback; // The last stack of statement (nodes) in the last error, or NULL sol_state_flag_t sflag; // Used to implement break/continue sol_object_t *error; // Some arbitrary error descriptor, None if no error sol_object_t *None; @@ -179,6 +181,9 @@ typedef struct sol_tag_state_t { sol_object_t *modules; sol_object_t *methods; dsl_object_funcs obfuncs; +#ifdef DEBUG_GC + dsl_seq *objects; +#endif } sol_state_t; // state.c @@ -201,6 +206,10 @@ sol_object_t *sol_set_error(sol_state_t *, sol_object_t *); sol_object_t *sol_set_error_string(sol_state_t *, const char *); void sol_clear_error(sol_state_t *); +void sol_init_traceback(sol_state_t *); +void sol_add_traceback(sol_state_t *, sol_object_t *); +sol_object_t *sol_traceback(sol_state_t *); + void sol_register_module(sol_state_t *, sol_object_t *, sol_object_t *); void sol_register_module_name(sol_state_t *, char *, sol_object_t *); sol_object_t *sol_get_module(sol_state_t *, sol_object_t *); @@ -239,6 +248,8 @@ sol_object_t *sol_f_exec(sol_state_t *, sol_object_t *); sol_object_t *sol_f_eval(sol_state_t *, sol_object_t *); sol_object_t *sol_f_execfile(sol_state_t *, sol_object_t *); sol_object_t *sol_f_parse(sol_state_t *, sol_object_t *); +sol_object_t *sol_f_ord(sol_state_t *, sol_object_t *); +sol_object_t *sol_f_chr(sol_state_t *, sol_object_t *); sol_object_t *sol_f_debug_getref(sol_state_t *, sol_object_t *); sol_object_t *sol_f_debug_setref(sol_state_t *, sol_object_t *); @@ -251,6 +262,8 @@ sol_object_t *sol_f_iter_str(sol_state_t *, sol_object_t *); sol_object_t *sol_f_iter_list(sol_state_t *, sol_object_t *); sol_object_t *sol_f_iter_map(sol_state_t *, sol_object_t *); +sol_object_t *sol_f_ast_print(sol_state_t *, sol_object_t *); + sol_object_t *sol_f_singlet_tostring(sol_state_t *, sol_object_t *); sol_object_t *sol_f_int_add(sol_state_t *, sol_object_t *); @@ -293,6 +306,7 @@ sol_object_t *sol_f_str_repr(sol_state_t *, sol_object_t *); sol_object_t *sol_f_str_sub(sol_state_t *, sol_object_t *); sol_object_t *sol_f_str_split(sol_state_t *, sol_object_t *); +sol_object_t *sol_f_str_find(sol_state_t *, sol_object_t *); sol_object_t *sol_f_list_add(sol_state_t *, sol_object_t *); sol_object_t *sol_f_list_mul(sol_state_t *, sol_object_t *); @@ -316,6 +330,7 @@ sol_object_t *sol_f_map_call(sol_state_t *, sol_object_t *); sol_object_t *sol_f_map_len(sol_state_t *, sol_object_t *); sol_object_t *sol_f_map_iter(sol_state_t *, sol_object_t *); sol_object_t *sol_f_map_tostring(sol_state_t *, sol_object_t *); +sol_object_t *sol_f_map_repr(sol_state_t *, sol_object_t *); sol_object_t *sol_f_mcell_tostring(sol_state_t *, sol_object_t *); @@ -368,18 +383,12 @@ sol_object_t *sol_f_stream_read(sol_state_t *, sol_object_t *); sol_object_t *sol_f_stream_seek(sol_state_t *, sol_object_t *); sol_object_t *sol_f_stream_tell(sol_state_t *, sol_object_t *); sol_object_t *sol_f_stream_flush(sol_state_t *, sol_object_t *); +sol_object_t *sol_f_stream_eof(sol_state_t *, sol_object_t *); sol_object_t *sol_f_stream_open(sol_state_t *, sol_object_t *); // object.c -#define sol_incref(obj) (++((obj)->refcnt), obj) -#define sol_decref(obj) (--((obj)->refcnt)) - -sol_object_t *sol_obj_acquire(sol_object_t *); -void sol_obj_free(sol_object_t *); -void sol_obj_release(sol_object_t *); - #define sol_is_singlet(obj) ((obj)->type == SOL_SINGLET) #define sol_is_none(state, obj) ((obj) == state->None) #define sol_is_oom(state, obj) ((obj) == state->OutOfMemory) @@ -398,8 +407,6 @@ void sol_obj_release(sol_object_t *); #define sol_has_error(state) (!sol_is_none((state), (state)->error)) -sol_object_t *sol_alloc_object(sol_state_t *); - sol_object_t *sol_new_singlet(sol_state_t *, const char *); sol_object_t *sol_new_int(sol_state_t *, long); sol_object_t *sol_new_float(sol_state_t *, double); @@ -454,14 +461,18 @@ sol_object_t *sol_new_dysym(sol_state_t *, void *, dsl_seq *, sol_buftype_t); sol_object_t *sol_new_stream(sol_state_t *, FILE *, sol_modes_t); size_t sol_stream_printf(sol_state_t *, sol_object_t *, const char *, ...); +size_t sol_stream_vprintf(sol_state_t *, sol_object_t *, const char *, va_list); size_t sol_stream_scanf(sol_state_t *, sol_object_t *, const char *, ...); size_t sol_stream_fread(sol_state_t *, sol_object_t *, char *, size_t, size_t); size_t sol_stream_fwrite(sol_state_t *, sol_object_t *, char *, size_t, size_t); char *sol_stream_fgets(sol_state_t *, sol_object_t *, char *, size_t); +int sol_stream_fputc(sol_state_t *, sol_object_t *, int); #define sol_printf(state, ...) sol_stream_printf(state, sol_get_stdout(state), __VA_ARGS__) +#define sol_vprintf(state, ...) sol_stream_vprintf(state, sol_get_stdout(state), __VA_ARGS__) #define sol_scanf(state, ...) sol_stream_scanf(state, sol_get_stdin(state, __VA_ARGS__) #define sol_fread(state, ...) sol_stream_fread(state, sol_get_stdin(state), __VA_ARGS__) #define sol_fwrite(state, ...) sol_stream_fwrite(state, sol_get_stdout(state), __VA_ARGS__) +#define sol_putchar(state, ...) sol_stream_fputc(state, sol_get_stdout(state), __VA_ARGS__) int sol_stream_feof(sol_state_t *, sol_object_t *); int sol_stream_ferror(sol_state_t *, sol_object_t *); #define sol_stream_ready(state, stream) (!(sol_stream_feof((state), (stream)) || sol_stream_ferror((state), (stream)))) @@ -489,6 +500,31 @@ int sol_validate_map(sol_state_t *, sol_object_t *); sol_object_t *sol_util_call(sol_state_t *, sol_object_t *, int *, int, ...); +// gc.c + +#ifdef DEBUG_GC + +sol_object_t *_int_sol_incref(const char *, sol_object_t *); +void _int_sol_obj_free(const char *, sol_object_t *); +#define sol_incref(obj) (_int_sol_incref(__func__, (obj))) +#define sol_obj_free(obj) (_int_sol_obj_free(__func__, (obj))) + +#else + +#define sol_incref(obj) (++((obj)->refcnt), obj) +void sol_obj_free(sol_object_t *); + +#endif + +#define sol_decref(obj) (--((obj)->refcnt)) + +sol_object_t *sol_obj_acquire(sol_object_t *); +void sol_obj_release(sol_object_t *); + +sol_object_t *sol_alloc_object(sol_state_t *); + +void sol_mm_finalize(sol_state_t *); + #define AS_OBJ(x) ((sol_object_t *) (x)) #endif diff --git a/solrun.c b/solrun.c index 65e85ea..1055827 100644 --- a/solrun.c +++ b/solrun.c @@ -41,10 +41,10 @@ int main(int argc, char **argv) { if(prgstream!=stdin) fclose(prgstream); - if(printtree) st_print(program); + sol_state_init(&state); + if(printtree) st_print(&state, program); if(program) { - sol_state_init(&state); sol_exec(&state, program); if(sol_has_error(&state)) { printf("Error: "); diff --git a/state.c b/state.c index 2076c9b..b338079 100644 --- a/state.c +++ b/state.c @@ -10,6 +10,7 @@ int sol_state_init(sol_state_t *state) { state->OutOfMemory = NULL; state->scopes = NULL; state->error = NULL; + state->traceback = NULL; state->ret = NULL; state->sflag = SF_NORMAL; @@ -102,6 +103,7 @@ int sol_state_init(sol_state_t *state) { state->MapOps.len = sol_f_map_len; state->MapOps.iter = sol_f_map_iter; state->MapOps.tostring = sol_f_map_tostring; + state->MapOps.repr = sol_f_map_repr; state->MapOps.free = sol_f_map_free; state->MCellOps.tname = "mcell"; @@ -178,6 +180,8 @@ int sol_state_init(sol_state_t *state) { sol_map_set_name(state, globals, "eval", sol_new_cfunc(state, sol_f_eval)); sol_map_set_name(state, globals, "execfile", sol_new_cfunc(state, sol_f_execfile)); sol_map_set_name(state, globals, "parse", sol_new_cfunc(state, sol_f_parse)); + sol_map_set_name(state, globals, "ord", sol_new_cfunc(state, sol_f_ord)); + sol_map_set_name(state, globals, "chr", sol_new_cfunc(state, sol_f_chr)); mod = sol_new_map(state); sol_map_set_name(state, mod, "getref", sol_new_cfunc(state, sol_f_debug_getref)); @@ -240,7 +244,12 @@ int sol_state_init(sol_state_t *state) { sol_map_set_name(state, mod, "OP_BNOT", sol_new_int(state, OP_BNOT)); sol_map_set_name(state, mod, "OP_LNOT", sol_new_int(state, OP_LNOT)); sol_map_set_name(state, mod, "OP_LEN", sol_new_int(state, OP_LEN)); + sol_map_set_name(state, mod, "LIT_INT", sol_new_int(state, LIT_INT)); + sol_map_set_name(state, mod, "LIT_FLOAT", sol_new_int(state, LIT_FLOAT)); + sol_map_set_name(state, mod, "LIT_STRING", sol_new_int(state, LIT_STRING)); + sol_map_set_name(state, mod, "LIT_NONE", sol_new_int(state, LIT_NONE)); sol_map_invert(state, mod); + sol_map_set_name(state, mod, "print", sol_new_cfunc(state, sol_f_ast_print)); sol_register_module_name(state, "ast", mod); btype = sol_new_map(state); @@ -360,12 +369,14 @@ int sol_state_init(sol_state_t *state) { sol_map_set_name(state, meths, "seek", sol_new_cfunc(state, sol_f_stream_seek)); sol_map_set_name(state, meths, "tell", sol_new_cfunc(state, sol_f_stream_tell)); sol_map_set_name(state, meths, "flush", sol_new_cfunc(state, sol_f_stream_flush)); + sol_map_set_name(state, meths, "eof", sol_new_cfunc(state, sol_f_stream_eof)); sol_register_methods_name(state, "stream", meths); sol_obj_free(meths); meths = sol_new_map(state); sol_map_set_name(state, meths, "sub", sol_new_cfunc(state, sol_f_str_sub)); sol_map_set_name(state, meths, "split", sol_new_cfunc(state, sol_f_str_split)); + sol_map_set_name(state, meths, "find", sol_new_cfunc(state, sol_f_str_find)); sol_register_methods_name(state, "string", meths); sol_obj_free(meths); @@ -387,7 +398,7 @@ void sol_state_cleanup(sol_state_t *state) { sol_obj_free(state->None); sol_obj_free(state->OutOfMemory); sol_obj_free(state->StopIteration); - sol_obj_free(state->ret); + if(state->ret) sol_obj_free(state->ret); sol_obj_free(state->modules); sol_obj_free(state->methods); } @@ -503,6 +514,7 @@ sol_object_t *sol_get_error(sol_state_t *state) { sol_object_t *sol_set_error(sol_state_t *state, sol_object_t *err) { state->error = sol_incref(err); + sol_init_traceback(state); return sol_incref(state->None); } @@ -524,6 +536,25 @@ void sol_clear_error(sol_state_t *state) { sol_obj_free(olderr); } +void sol_init_traceback(sol_state_t *state) { + if(state->traceback) sol_obj_free(state->traceback); + state->traceback = sol_new_list(state); +} + +void sol_add_traceback(sol_state_t *state, sol_object_t *node) { + sol_object_t *pair = sol_new_list(state), *scope = sol_list_get_index(state, state->scopes, 0); + sol_list_insert(state, pair, 0, node); + sol_list_insert(state, pair, 1, scope); + sol_obj_free(scope); + sol_list_insert(state, state->traceback, 0, pair); + sol_obj_free(pair); +} + +sol_object_t *sol_traceback(sol_state_t *state) { + if(state->traceback) return sol_incref(state->traceback); + return sol_incref(state->None); +} + void sol_register_module(sol_state_t *state, sol_object_t *key, sol_object_t *val) { sol_map_set(state, state->modules, key, val); } diff --git a/test.sol b/test.sol index 5e23756..8fcf7a2 100644 --- a/test.sol +++ b/test.sol @@ -391,4 +391,19 @@ for i in l do prepr(i, type(i)) end +print('--- Continue/break') + +l = range(10) +for i in l do + print(i) + if i >= 5 then break end +end + +print('---') + +for i in l do + if i%2 == 0 then continue end + print(i) +end + print('--- All done!') diff --git a/test_monty.sol b/test_monty.sol new file mode 100644 index 0000000..381c269 --- /dev/null +++ b/test_monty.sol @@ -0,0 +1,10 @@ +execfile('monty.sol') +t = tokenizer.new(io.open('/tmp/monty', io.MODE_READ)) +ttg = ttreegen.new(t) +p = parser.new(ttg) +c = converter.new(p) +stmt = c:run() +print('Resulting statement:') +ast.print(stmt) +print('---Running results begin here---') +stmt()