Browse Source

Merge pull request #15 from sol-lang/grissess_stmt-exprs

Sol Part 43: EXPRESSIONS EVERYWHERE
master
Benjamin Lannon 6 years ago
parent
commit
7ff1611a5d
  1. 50
      ast.h
  2. 66
      astprint.c
  3. 160
      builtins.c
  4. 16328
      parser.output
  5. 1105
      parser.tab.c
  6. 49
      parser.y
  7. 8
      programs/fizzbuzz.sol
  8. 228
      runtime.c
  9. 6
      sol.h
  10. 11
      state.c

50
ast.h

@ -98,7 +98,24 @@ typedef struct {
stmt_node *body;
} funcdecl_node;
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 {
expr_node *cond;
stmt_node *iftrue;
stmt_node *iffalse;
} ifelse_node;
typedef struct {
expr_node *cond;
stmt_node *loop;
} loop_node;
typedef struct {
char *var;
expr_node *iter;
stmt_node *loop;
} iter_node;
typedef enum {EX_LIT, EX_LISTGEN, EX_MAPGEN, EX_BINOP, EX_UNOP, EX_INDEX, EX_SETINDEX, EX_ASSIGN, EX_REF, EX_CALL, EX_FUNCDECL, EX_IFELSE, EX_LOOP, EX_ITER} expr_t;
typedef struct tag_expr_node {
expr_t type;
loc_t loc;
@ -114,46 +131,39 @@ typedef struct tag_expr_node {
ref_node *ref;
call_node *call;
funcdecl_node *funcdecl;
ifelse_node *ifelse;
loop_node *loop;
iter_node *iter;
};
} expr_node;
typedef struct {
expr_node *cond;
stmt_node *iftrue;
stmt_node *iffalse;
} ifelse_node;
typedef struct {
expr_node *cond;
stmt_node *loop;
} loop_node;
expr_node *ret;
} ret_node;
typedef struct {
char *var;
expr_node *iter;
stmt_node *loop;
} iter_node;
expr_node *val;
} cont_node;
typedef struct {
expr_node *ret;
} ret_node;
expr_node *val;
} break_node;
typedef struct tag_stmtlist_node {
stmt_node *stmt;
struct tag_stmtlist_node *next;
} stmtlist_node;
typedef enum {ST_EXPR, ST_IFELSE, ST_LOOP, ST_ITER, ST_LIST, ST_RET, ST_CONT, ST_BREAK} stmt_t;
typedef enum {ST_EXPR, 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;
loop_node *loop;
iter_node *iter;
stmtlist_node *stmtlist;
ret_node *ret;
cont_node *cont;
break_node *brk;
};
} stmt_node;

66
astprint.c

@ -31,36 +31,6 @@ void prst(sol_state_t *state, stmt_node *node, int lev) {
prex(state, node->expr, lev + 1);
break;
case ST_IFELSE:
prlev(state, lev, "Stmt<IfElse>:");
lev++;
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(state, lev, "Stmt<Loop>:");
lev++;
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(state, lev, "Stmt<Iter>:");
lev++;
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(state, lev, "Stmt<List>:");
stmtlist_node *cur = node->stmtlist;
@ -76,11 +46,13 @@ void prst(sol_state_t *state, stmt_node *node, int lev) {
break;
case ST_CONT:
prlev(state, lev, "Stmt<Continue>");
prlev(state, lev, "Stmt<Continue>:");
prex(state, node->cont->val, lev + 1);
break;
case ST_BREAK:
prlev(state, lev, "Stmt<Break>");
prlev(state, lev, "Stmt<Break>:");
prex(state, node->brk->val, lev + 1);
break;
}
}
@ -306,6 +278,36 @@ void prex(sol_state_t *state, expr_node *node, int lev) {
prlev(state, lev, "Body:");
prst(state, node->funcdecl->body, lev + 1);
break;
case EX_IFELSE:
prlev(state, lev, "Expr<IfElse>:");
lev++;
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 EX_LOOP:
prlev(state, lev, "Expr<Loop>:");
lev++;
prlev(state, lev, "Cond:");
prex(state, node->loop->cond, lev + 1);
prlev(state, lev, "Loop:");
prst(state, node->loop->loop, lev + 1);
break;
case EX_ITER:
prlev(state, lev, "Expr<Iter>:");
lev++;
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;
}
}

160
builtins.c

@ -1572,34 +1572,6 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
}
break;
case ST_IFELSE:
if(sol_string_eq(state, str, "cond")) {
res = sol_new_exprnode(state, ex_copy(stmt->ifelse->cond));
} else if(sol_string_eq(state, str, "iftrue")) {
res = sol_new_stmtnode(state, st_copy(stmt->ifelse->iftrue));
} else if(sol_string_eq(state, str, "iffalse")) {
res = sol_new_stmtnode(state, st_copy(stmt->ifelse->iffalse));
}
break;
case ST_LOOP:
if(sol_string_eq(state, str, "cond")) {
res = sol_new_exprnode(state, ex_copy(stmt->loop->cond));
} else if(sol_string_eq(state, str, "loop")) {
res = sol_new_stmtnode(state, st_copy(stmt->loop->loop));
}
break;
case ST_ITER:
if(sol_string_eq(state, str, "var")) {
res = sol_new_string(state, stmt->iter->var);
} else if(sol_string_eq(state, str, "iter")) {
res = sol_new_exprnode(state, ex_copy(stmt->iter->iter));
} else if(sol_string_eq(state, str, "loop")) {
res = sol_new_stmtnode(state, st_copy(stmt->iter->loop));
}
break;
case ST_LIST:
if(sol_string_eq(state, str, "stmtlist")) {
res = sol_new_list(state);
@ -1616,6 +1588,18 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
res = sol_new_exprnode(state, ex_copy(stmt->ret->ret));
}
break;
case ST_CONT:
if(sol_string_eq(state, str, "val")) {
res = sol_new_exprnode(state, ex_copy(stmt->cont->val));
}
break;
case ST_BREAK:
if(sol_string_eq(state, str, "val")) {
res = sol_new_exprnode(state, ex_copy(stmt->brk->val));
}
break;
}
}
} else {
@ -1741,6 +1725,34 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
res = sol_new_stmtnode(state, st_copy(expr->funcdecl->body));
}
break;
case EX_IFELSE:
if(sol_string_eq(state, str, "cond")) {
res = sol_new_exprnode(state, ex_copy(expr->ifelse->cond));
} else if(sol_string_eq(state, str, "iftrue")) {
res = sol_new_stmtnode(state, st_copy(expr->ifelse->iftrue));
} else if(sol_string_eq(state, str, "iffalse")) {
res = sol_new_stmtnode(state, st_copy(expr->ifelse->iffalse));
}
break;
case EX_LOOP:
if(sol_string_eq(state, str, "cond")) {
res = sol_new_exprnode(state, ex_copy(expr->loop->cond));
} else if(sol_string_eq(state, str, "loop")) {
res = sol_new_stmtnode(state, st_copy(expr->loop->loop));
}
break;
case EX_ITER:
if(sol_string_eq(state, str, "var")) {
res = sol_new_string(state, expr->iter->var);
} else if(sol_string_eq(state, str, "iter")) {
res = sol_new_exprnode(state, ex_copy(expr->iter->iter));
} else if(sol_string_eq(state, str, "loop")) {
res = sol_new_stmtnode(state, st_copy(expr->iter->loop));
}
break;
}
}
}
@ -1795,43 +1807,6 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
}
break;
case ST_IFELSE:
if(sol_string_eq(state, str, "cond") && sol_is_astexpr(val)) {
ex_free(stmt->ifelse->cond);
stmt->ifelse->cond = ex_copy(val->node);
} else if(sol_string_eq(state, str, "iftrue") && sol_is_aststmt(val)) {
st_free(stmt->ifelse->iftrue);
stmt->ifelse->iftrue = st_copy(val->node);
} else if(sol_string_eq(state, str, "iffalse") && sol_is_aststmt(val)) {
st_free(stmt->ifelse->iffalse);
stmt->ifelse->iffalse = st_copy(val->node);
}
break;
case ST_LOOP:
if(sol_string_eq(state, str, "cond") && sol_is_astexpr(val)) {
ex_free(stmt->loop->cond);
stmt->loop->cond = ex_copy(val->node);
} else if(sol_string_eq(state, str, "loop") && sol_is_aststmt(val)) {
st_free(stmt->loop->loop);
stmt->loop->loop = st_copy(val->node);
}
break;
case ST_ITER:
if(sol_string_eq(state, str, "var")) {
sval = sol_cast_string(state, val);
stmt->iter->var = strdup(sval->str);
sol_obj_free(sval);
} else if(sol_string_eq(state, str, "iter") && sol_is_astexpr(val)) {
ex_free(stmt->iter->iter);
stmt->iter->iter = ex_copy(val->node);
} else if(sol_string_eq(state, str, "loop") && sol_is_aststmt(val)) {
st_free(stmt->iter->loop);
stmt->iter->loop = st_copy(val->node);
}
break;
case ST_LIST:
if(sol_string_eq(state, str, "stmtlist") && sol_is_list(val)) {
stl_free(stmt->stmtlist);
@ -1866,6 +1841,20 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
stmt->ret->ret = ex_copy(val->node);
}
break;
case ST_CONT:
if(sol_string_eq(state, str, "val") && sol_is_astexpr(val)) {
ex_free(stmt->cont->val);
stmt->cont->val = ex_copy(val->node);
}
break;
case ST_BREAK:
if(sol_string_eq(state, str, "val") && sol_is_astexpr(val)) {
ex_free(stmt->brk->val);
stmt->brk->val = ex_copy(val->node);
}
break;
}
}
} else {
@ -2099,6 +2088,43 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
expr->funcdecl->body = st_copy(val->node);
}
break;
case EX_IFELSE:
if(sol_string_eq(state, str, "cond") && sol_is_astexpr(val)) {
ex_free(expr->ifelse->cond);
expr->ifelse->cond = ex_copy(val->node);
} else if(sol_string_eq(state, str, "iftrue") && sol_is_aststmt(val)) {
st_free(expr->ifelse->iftrue);
expr->ifelse->iftrue = st_copy(val->node);
} else if(sol_string_eq(state, str, "iffalse") && sol_is_aststmt(val)) {
st_free(expr->ifelse->iffalse);
expr->ifelse->iffalse = st_copy(val->node);
}
break;
case EX_LOOP:
if(sol_string_eq(state, str, "cond") && sol_is_astexpr(val)) {
ex_free(expr->loop->cond);
expr->loop->cond = ex_copy(val->node);
} else if(sol_string_eq(state, str, "loop") && sol_is_aststmt(val)) {
st_free(expr->loop->loop);
expr->loop->loop = st_copy(val->node);
}
break;
case EX_ITER:
if(sol_string_eq(state, str, "var")) {
sval = sol_cast_string(state, val);
expr->iter->var = strdup(sval->str);
sol_obj_free(sval);
} else if(sol_string_eq(state, str, "iter") && sol_is_astexpr(val)) {
ex_free(expr->iter->iter);
expr->iter->iter = ex_copy(val->node);
} else if(sol_string_eq(state, str, "loop") && sol_is_aststmt(val)) {
st_free(expr->iter->loop);
expr->iter->loop = st_copy(val->node);
}
break;
}
}
}
@ -2108,8 +2134,8 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
return val;
}
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"};
static char *sol_StmtNames[] = {"EXPR", "LIST", "RET", "CONT", "BREAK"};
static char *sol_ExprNames[] = {"LIT", "LISTGEN", "MAPGEN", "BINOP", "UNOP", "INDEX", "SETINDEX", "ASSIGN", "REF", "CALL", "FUNCDECL", "IFELSE", "LOOP", "ITER"};
sol_object_t *sol_f_astnode_tostring(sol_state_t *state, sol_object_t *args) {
sol_object_t *obj = sol_list_get_index(state, args, 0), *res;

16328
parser.output
File diff suppressed because it is too large
View File

1105
parser.tab.c
File diff suppressed because it is too large
View File

49
parser.y

@ -56,18 +56,55 @@ stmt_list:
stmt:
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; }
| BREAK { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_BREAK; AS_ST($$)->brk = NEW(break_node); }
| BREAK expr { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_BREAK; AS_ST($$)->brk = NEW(break_node); AS_ST($$)->brk->val = $2; }
| CONTINUE { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_CONT; AS_ST($$)->cont = NEW(cont_node); }
| CONTINUE expr { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_CONT; AS_ST($$)->cont = NEW(cont_node); AS_ST($$)->cont->val = $2; }
| stmt SEMICOLON { $$ = $1; }
;
expr:
control_expr { $$ = $1; }
;
control_expr:
IF expr THEN stmt_list END {
$$ = NEW_EX();
AS_EX($$)->type = EX_IFELSE;
AS_EX($$)->ifelse = NEW(ifelse_node);
AS_EX($$)->ifelse->cond = $2;
AS_EX($$)->ifelse->iftrue = $4;
AS_EX($$)->ifelse->iffalse = NULL;
}
| IF expr THEN stmt_list ELSE stmt_list END {
$$ = NEW_EX();
AS_EX($$)->type = EX_IFELSE;
AS_EX($$)->ifelse = NEW(ifelse_node);
AS_EX($$)->ifelse->cond = $2;
AS_EX($$)->ifelse->iftrue = $4;
AS_EX($$)->ifelse->iffalse = $6;
}
| WHILE expr DO stmt_list END {
$$ = NEW_EX();
AS_EX($$)->type = EX_LOOP;
AS_EX($$)->loop = NEW(loop_node);
AS_EX($$)->loop->cond = $2;
AS_EX($$)->loop->loop = $4;
}
| FOR IDENT IN expr DO stmt_list END {
$$ = NEW_EX();
AS_EX($$)->type = EX_ITER;
AS_EX($$)->iter = NEW(iter_node);
AS_EX($$)->iter->var = $2;
AS_EX($$)->iter->iter = $4;
AS_EX($$)->iter->loop = $6;
}
| assign_expr { $$ = $1; }
;
assign_expr:
IDENT ASSIGN expr { $$ = NEW_EX(); AS_EX($$)->type = EX_ASSIGN; AS_EX($$)->assign = NEW(assign_node); AS_EX($$)->assign->ident = $1; AS_EX($$)->assign->value = $3; }
| IDENT ASSIGNPLUS expr {
$$ = NEW_EX();

8
programs/fizzbuzz.sol

@ -0,0 +1,8 @@
ID = lambda(x) x end
FIZZ = lambda(x) 'FIZZ' end
BUZZ = lambda(x) 'BUZZ' end
FIZZBUZZ = lambda(x) 'FIZZBUZZ' end
L = [FIZZBUZZ] + (for i in range(14) do if !((i + 1) % 3) then continue FIZZ end if !((i + 1) % 5) then continue BUZZ end continue ID end)
func fizzbuzz(s, e) return for i in range(e-s) do continue L[(i + s)%(#L)](i + s) end end
for i in fizzbuzz(1, 101) do print(i) end

228
runtime.c

@ -20,7 +20,7 @@ stmt_node *st_copy(stmt_node *old) {
stmt_node *new;
stmtlist_node *curn, *curo;
if(!old) {
printf("WARNING: Copying NULL statement\n");
// printf("WARNING: Copying NULL statement\n");
return NULL;
}
new = NEW(stmt_node);
@ -30,34 +30,7 @@ stmt_node *st_copy(stmt_node *old) {
new->expr = ex_copy(old->expr);
break;
case ST_IFELSE:
new->ifelse = NEW(ifelse_node);
new->ifelse->cond = ex_copy(old->ifelse->cond);
if(old->ifelse->iftrue)
new->ifelse->iftrue = st_copy(old->ifelse->iftrue);
else
new->ifelse->iftrue = NULL;
if(old->ifelse->iffalse)
new->ifelse->iffalse = st_copy(old->ifelse->iffalse);
else
new->ifelse->iffalse = NULL;
break;
case ST_LOOP:
new->loop = NEW(loop_node);
new->loop->cond = ex_copy(old->loop->cond);
new->loop->loop = st_copy(old->loop->loop);
break;
case ST_ITER:
new->iter = NEW(iter_node);
new->iter->var = strdup(old->iter->var);
new->iter->iter = ex_copy(old->iter->iter);
new->iter->loop = st_copy(old->iter->loop);
break;
case ST_LIST:
new->stmtlist = stl_copy(old->stmtlist);
break;
@ -67,7 +40,13 @@ stmt_node *st_copy(stmt_node *old) {
break;
case ST_CONT:
new->cont = NEW(cont_node);
new->cont->val = ex_copy(old->cont->val);
break;
case ST_BREAK:
new->brk = NEW(break_node);
new->brk->val = ex_copy(old->cont->val);
break;
default:
@ -107,7 +86,7 @@ expr_node *ex_copy(expr_node *old) {
assoclist_node *curao, *curan;
identlist_node *curio, *curin;
if(!old) {
printf("WARNING: Copying NULL expression\n");
// printf("WARNING: Copying NULL expression\n");
return NULL;
}
new = NEW(expr_node);
@ -202,6 +181,32 @@ expr_node *ex_copy(expr_node *old) {
new->funcdecl->body = st_copy(old->funcdecl->body);
break;
case EX_IFELSE:
new->ifelse = NEW(ifelse_node);
new->ifelse->cond = ex_copy(old->ifelse->cond);
if(old->ifelse->iftrue)
new->ifelse->iftrue = st_copy(old->ifelse->iftrue);
else
new->ifelse->iftrue = NULL;
if(old->ifelse->iffalse)
new->ifelse->iffalse = st_copy(old->ifelse->iffalse);
else
new->ifelse->iffalse = NULL;
break;
case EX_LOOP:
new->loop = NEW(loop_node);
new->loop->cond = ex_copy(old->loop->cond);
new->loop->loop = st_copy(old->loop->loop);
break;
case EX_ITER:
new->iter = NEW(iter_node);
new->iter->var = strdup(old->iter->var);
new->iter->iter = ex_copy(old->iter->iter);
new->iter->loop = st_copy(old->iter->loop);
break;
default:
printf("WARNING: Unknown expression type to copy: %d\n", old->type);
break;
@ -295,26 +300,6 @@ void st_free(stmt_node *stmt) {
ex_free(stmt->expr);
break;
case ST_IFELSE:
ex_free(stmt->ifelse->cond);
st_free(stmt->ifelse->iftrue);
st_free(stmt->ifelse->iffalse);
free(stmt->ifelse);
break;
case ST_LOOP:
ex_free(stmt->loop->cond);
st_free(stmt->loop->loop);
free(stmt->loop);
break;
case ST_ITER:
free(stmt->iter->var);
ex_free(stmt->iter->iter);
st_free(stmt->iter->loop);
free(stmt->iter);
break;
case ST_LIST:
stl_free(stmt->stmtlist);
break;
@ -325,8 +310,12 @@ void st_free(stmt_node *stmt) {
break;
case ST_CONT:
ex_free(stmt->cont->val);
break;
case ST_BREAK:
break; // Make the compiler happy :D
ex_free(stmt->brk->val);
break;
}
free(stmt);
}
@ -415,6 +404,26 @@ void ex_free(expr_node *expr) {
idl_free(expr->funcdecl->args);
free(expr->funcdecl);
break;
case EX_IFELSE:
ex_free(expr->ifelse->cond);
st_free(expr->ifelse->iftrue);
st_free(expr->ifelse->iffalse);
free(expr->ifelse);
break;
case EX_LOOP:
ex_free(expr->loop->cond);
st_free(expr->loop->loop);
free(expr->loop);
break;
case EX_ITER:
free(expr->iter->var);
ex_free(expr->iter->iter);
st_free(expr->iter->loop);
free(expr->iter);
break;
}
free(expr);
}
@ -459,7 +468,7 @@ void idl_free(identlist_node *list) {
#define ERR_CHECK(state) do { if(sol_has_error(state)) longjmp(jmp, 1); } while(0)
sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
sol_object_t *res, *left, *right, *lint, *rint, *value, *list;
sol_object_t *res, *left, *right, *lint, *rint, *value, *list, *vint, *iter, *item;
exprlist_node *cure;
assoclist_node *cura;
if(!expr) {
@ -756,80 +765,52 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
}
return res;
break;
}
printf("WARNING: Unhandled expression (type %d) returning None\n", expr->type);
return sol_incref(state->None);
}
sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
jmp_buf jmp;
if(!setjmp(jmp)) {
return sol_eval_inner(state, expr, jmp);
} else {
return sol_incref(state->None);
}
}
void sol_exec(sol_state_t *state, stmt_node *stmt) {
sol_object_t *value, *vint, *list, *iter, *item;
stmtlist_node *curs;
if(!stmt) {
sol_obj_free(sol_set_error_string(state, "Execute NULL statement"));
return;
}
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, st_copy(stmt)));
}
break;
case ST_IFELSE:
value = sol_eval(state, stmt->ifelse->cond);
case EX_IFELSE:
value = sol_eval(state, expr->ifelse->cond);
vint = sol_cast_int(state, value);
if(vint->ival) {
if(stmt->ifelse->iftrue) {
sol_exec(state, stmt->ifelse->iftrue);
if(expr->ifelse->iftrue) {
sol_exec(state, expr->ifelse->iftrue);
}
} else {
if(stmt->ifelse->iffalse) {
sol_exec(state, stmt->ifelse->iffalse);
if(expr->ifelse->iffalse) {
sol_exec(state, expr->ifelse->iffalse);
}
}
sol_obj_free(value);
sol_obj_free(vint);
if(sol_has_error(state)) {
sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
}
return sol_incref(state->lastvalue);
break;
case ST_LOOP:
value = sol_eval(state, stmt->loop->cond);
case EX_LOOP:
sol_obj_free(state->loopvalue);
state->loopvalue = sol_new_list(state);
value = sol_eval(state, expr->loop->cond);
vint = sol_cast_int(state, value);
while(vint->ival) {
sol_obj_free(value);
sol_obj_free(vint);
sol_exec(state, stmt->loop->loop);
sol_exec(state, expr->loop->loop);
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);
value = sol_eval(state, expr->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, st_copy(stmt)));
}
sol_obj_free(value);
sol_obj_free(vint);
return sol_incref(state->loopvalue);
break;
case ST_ITER:
value = sol_eval(state, stmt->iter->iter);
case EX_ITER:
sol_obj_free(state->loopvalue);
state->loopvalue = sol_new_list(state);
value = sol_eval(state, expr->iter->iter);
if(value->ops->iter && value->ops->iter != sol_f_not_impl) {
list = sol_new_list(state);
sol_list_insert(state, list, 0, value);
@ -840,7 +821,7 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
}
if(!iter->ops->call || iter->ops->call == sol_f_not_impl) {
sol_obj_free(sol_set_error_string(state, "Iterate over non-iterable"));
return;
return sol_incref(state->None);
}
list = sol_new_list(state);
sol_list_insert(state, list, 0, iter);
@ -848,8 +829,8 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
sol_list_insert(state, list, 2, sol_new_map(state));
item = CALL_METHOD(state, iter, call, list);
while(item != state->StopIteration) {
sol_state_assign_l_name(state, stmt->iter->var, item);
sol_exec(state, stmt->iter->loop);
sol_state_assign_l_name(state, expr->iter->var, item);
sol_exec(state, expr->iter->loop);
sol_obj_free(item);
if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) {
item = sol_incref(state->StopIteration);
@ -858,13 +839,41 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
item = CALL_METHOD(state, iter, call, list);
}
state->sflag = SF_NORMAL;
if(sol_has_error(state)) {
sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
}
sol_obj_free(iter);
sol_obj_free(value);
sol_obj_free(list);
sol_obj_free(item);
return sol_incref(state->loopvalue);
break;
}
printf("WARNING: Unhandled expression (type %d) returning None\n", expr->type);
return sol_incref(state->None);
}
sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
jmp_buf jmp;
if(!setjmp(jmp)) {
return sol_eval_inner(state, expr, jmp);
} else {
return sol_incref(state->None);
}
}
void sol_exec(sol_state_t *state, stmt_node *stmt) {
sol_object_t *value, *vint, *list, *iter, *item;
stmtlist_node *curs;
if(!stmt) {
sol_obj_free(sol_set_error_string(state, "Execute NULL statement"));
return;
}
switch(stmt->type) {
case ST_EXPR:
value = state->lastvalue;
state->lastvalue = sol_eval(state, stmt->expr);
sol_obj_free(value);
if(sol_has_error(state)) {
sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
}
break;
case ST_LIST:
@ -892,10 +901,23 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
break;
case ST_CONT:
if(stmt->cont->val && sol_is_list(state->loopvalue)) {
value = sol_eval(state, stmt->cont->val);
sol_list_insert(state, state->loopvalue, sol_list_len(state, state->loopvalue), value);
sol_obj_free(value);
}
state->sflag = SF_CONTINUING;
break;
case ST_BREAK:
if(stmt->brk->val) {
value = sol_eval(state, stmt->brk->val);
} else {
value = sol_incref(state->None);
}
vint = state->loopvalue;
state->loopvalue = sol_incref(value);
sol_obj_free(vint);
state->sflag = SF_BREAKING;
break;

6
sol.h

@ -9,8 +9,8 @@
#include <stdarg.h>
#include "dsl/dsl.h"
#define VERSION "0.1a5"
#define HEXVER 0x0001A05
#define VERSION "0.2a0"
#define HEXVER 0x0002A00
#ifndef SOL_ICACHE_MIN
#define SOL_ICACHE_MIN -128
@ -202,6 +202,8 @@ typedef struct sol_tag_state_t {
sol_object_t *icache[SOL_ICACHE_MAX - SOL_ICACHE_MIN + 1];
char icache_bypass;
#endif
sol_object_t *lastvalue;
sol_object_t *loopvalue;
} sol_state_t;
// state.c

11
state.c

@ -16,6 +16,8 @@ int sol_state_init(sol_state_t *state) {
state->traceback = NULL;
state->ret = NULL;
state->sflag = SF_NORMAL;
state->lastvalue = NULL;
state->loopvalue = NULL;
#ifdef DEBUG_GC
// This is necessary for DEBUG_GC's early allocation; it gets overwritten,
@ -186,6 +188,9 @@ int sol_state_init(sol_state_t *state) {
state->calling_type = "(none)";
state->calling_meth = "(none)";
state->lastvalue = sol_incref(state->None);
state->loopvalue = sol_incref(state->None);
state->error = state->None;
state->scopes = sol_new_list(state);
if(sol_has_error(state)) {
@ -259,9 +264,6 @@ int sol_state_init(sol_state_t *state) {
mod = sol_new_map(state);
sol_map_borrow_name(state, mod, "ST_EXPR", sol_new_int(state, ST_EXPR));
sol_map_borrow_name(state, mod, "ST_IFELSE", sol_new_int(state, ST_IFELSE));
sol_map_borrow_name(state, mod, "ST_LOOP", sol_new_int(state, ST_LOOP));
sol_map_borrow_name(state, mod, "ST_ITER", sol_new_int(state, ST_ITER));
sol_map_borrow_name(state, mod, "ST_LIST", sol_new_int(state, ST_LIST));
sol_map_borrow_name(state, mod, "ST_RET", sol_new_int(state, ST_RET));
sol_map_borrow_name(state, mod, "ST_CONT", sol_new_int(state, ST_CONT));
@ -277,6 +279,9 @@ int sol_state_init(sol_state_t *state) {
sol_map_borrow_name(state, mod, "EX_REF", sol_new_int(state, EX_LIT));
sol_map_borrow_name(state, mod, "EX_CALL", sol_new_int(state, EX_LIT));
sol_map_borrow_name(state, mod, "EX_FUNCDECL", sol_new_int(state, EX_LIT));
sol_map_borrow_name(state, mod, "EX_IFELSE", sol_new_int(state, EX_IFELSE));
sol_map_borrow_name(state, mod, "EX_LOOP", sol_new_int(state, EX_LOOP));
sol_map_borrow_name(state, mod, "EX_ITER", sol_new_int(state, EX_ITER));
sol_map_borrow_name(state, mod, "OP_ADD", sol_new_int(state, OP_ADD));
sol_map_borrow_name(state, mod, "OP_SUB", sol_new_int(state, OP_SUB));
sol_map_borrow_name(state, mod, "OP_MUL", sol_new_int(state, OP_MUL));

Loading…
Cancel
Save