Browse Source

Sol Part 7: The Update that Saved the World

master
Grissess 7 years ago
parent
commit
406a03c15e
  1. 103
      builtins.c
  2. 242
      cdata.c
  3. 19
      cdata.h
  4. 33
      object.c
  5. 17288
      parser.output
  6. 1056
      parser.tab.c
  7. 62
      parser.y
  8. 11
      sol.h
  9. 8
      state.c
  10. 76
      test.sol

103
builtins.c

@ -646,8 +646,15 @@ sol_object_t *sol_f_list_mul(sol_state_t *state, sol_object_t *args) {
}
sol_object_t *sol_f_list_index(sol_state_t *state, sol_object_t *args) {
sol_object_t *ls = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
sol_object_t *res = sol_list_get_index(state, ls, b->ival);
sol_object_t *ls = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *ival;
sol_object_t *res;
if(sol_is_string(b)) {
res = sol_map_get(state, state->ListFuncs, b);
} else {
ival = sol_cast_int(state, b);
res = sol_list_get_index(state, ls, ival->ival);
if(ival!=b) sol_obj_free(ival);
}
sol_obj_free(ls);
sol_obj_free(b);
return res;
@ -678,6 +685,81 @@ sol_object_t *sol_f_list_tostring(sol_state_t *state, sol_object_t *args) {
return sol_new_string(state, "<List>");
}
sol_object_t *sol_f_list_copy(sol_state_t *state, sol_object_t *args) {
sol_object_t *list = sol_list_get_index(state, args, 0);
sol_object_t *res = sol_list_copy(state, list);
sol_obj_free(list);
return res;
}
sol_object_t *sol_f_list_insert(sol_state_t *state, sol_object_t *args) {
sol_object_t *list = sol_list_get_index(state, args, 0), *idx = sol_cast_int(state, sol_list_get_index(state, args, 1)), *obj = sol_list_get_index(state, args, 2);
sol_list_insert(state, list, idx->ival, obj);
sol_obj_free(list);
return sol_incref(state->None);
}
sol_object_t *sol_f_list_remove(sol_state_t *state, sol_object_t *args) {
sol_object_t *list = sol_list_get_index(state, args, 0), *idx = sol_cast_int(state, sol_list_get_index(state, args, 1));
sol_list_remove(state, list, idx->ival);
sol_obj_free(list);
return sol_incref(state->None);
}
sol_object_t *sol_f_list_truncate(sol_state_t *state, sol_object_t *args) {
sol_object_t *list = sol_list_get_index(state, args, 0), *idx = sol_list_get_index(state, args, 1);
sol_object_t *res = sol_list_truncate(state, list, idx->ival);
sol_obj_free(list);
return res;
}
sol_object_t *sol_f_list_map(sol_state_t *state, sol_object_t *args) {
sol_object_t *list = sol_list_get_index(state, args, 0), *func = sol_list_get_index(state, args, 1);
sol_object_t *fargs = sol_new_list(state), *item;
int idx=0, len = sol_list_len(state, list);
sol_list_insert(state, fargs, 0, func);
while(idx<len) {
item = sol_list_get_index(state, list, idx);
sol_list_insert(state, fargs, 1, item);
sol_obj_free(item);
item = func->ops->call(state, fargs);
if(sol_has_error(state)) return list;
sol_list_remove(state, fargs, 1);
sol_list_set_index(state, list, idx, item);
sol_obj_free(item);
idx++;
}
sol_obj_free(fargs);
sol_obj_free(func);
return list;
}
sol_object_t *sol_f_list_filter(sol_state_t *state, sol_object_t *args) {
sol_object_t *list = sol_list_get_index(state, args, 0), *func = sol_list_get_index(state, args, 1);
sol_object_t *fargs = sol_new_list(state), *item, *ival;
int idx=0, len = sol_list_len(state, list);
sol_list_insert(state, fargs, 0, func);
while(idx<len) {
item = sol_list_get_index(state, list, idx);
sol_list_insert(state, fargs, 1, item);
sol_obj_free(item);
item = func->ops->call(state, fargs);
if(sol_has_error(state)) return list;
ival = sol_cast_int(state, item);
if(ival->ival) {
idx++;
} else {
sol_list_remove(state, list, idx);
len--;
}
if(ival!=item) sol_obj_free(item);
sol_obj_free(ival);
}
sol_obj_free(fargs);
sol_obj_free(func);
return list;
}
sol_object_t *sol_f_map_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), *map;
if(!sol_is_map(b)) {
@ -697,14 +779,18 @@ sol_object_t *sol_f_map_index(sol_state_t *state, sol_object_t *args) {
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 && indexf->ops->call != sol_f_not_impl) {
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) {
res = indexf->ops->index(state, args);
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);
@ -719,7 +805,7 @@ sol_object_t *sol_f_map_setindex(sol_state_t *state, sol_object_t *args) {
sol_object_t *val = sol_list_get_index(state, args, 2);
sol_object_t *setindexf = sol_map_get_name(state, map, "__setindex"), *newls;
if(!sol_is_none(state, setindexf)) {
if(setindexf->ops->call && setindexf->ops->call != sol_f_not_impl) {
if(setindexf->ops->call && (sol_is_func(setindexf) || sol_is_cfunc(setindexf)) && setindexf->ops->call != sol_f_not_impl) {
newls = sol_new_list(state);
sol_list_insert(state, newls, 0, setindexf);
sol_list_append(state, newls, args);
@ -727,7 +813,12 @@ sol_object_t *sol_f_map_setindex(sol_state_t *state, sol_object_t *args) {
sol_obj_free(newls);
return sol_incref(state->None);
} else if(setindexf->ops->setindex && setindexf->ops->setindex != sol_f_not_impl) {
setindexf->ops->setindex(state, args);
newls = sol_new_list(state);
sol_list_insert(state, newls, 0, setindexf);
sol_list_insert(state, newls, 1, b);
sol_list_insert(state, newls, 2, val);
sol_obj_free(setindexf->ops->index(state, newls));
sol_obj_free(newls);
return sol_incref(state->None);
}
}

242
cdata.c

@ -0,0 +1,242 @@
#include "cdata.h"
#include <stdint.h>
#include <string.h>
#define AS(arg, tp) ((tp *) (arg))
#define AT(loc, tp, off) (*((tp *) ((char *) loc) + off))
#define NEW(tp) malloc(sizeof(tp))
#define ENSURE() if(!sol_cstruct_is_init) sol_cstruct_init()
int sol_cstruct_is_init = 0;
extern sol_ops_t sol_cstruct_spec_ops;
extern sol_ops_t sol_cstruct_ops;
void sol_cstruct_init(void) {
sol_ops_init(&sol_cstruct_spec_ops);
sol_ops_init(&sol_cstruct_ops);
sol_cstruct_ops.index = sol_f_cstruct_index;
sol_cstruct_ops.setindex = sol_f_cstruct_setindex;
sol_cstruct_is_init = 1;
}
sol_object_t *sol_new_cstruct_specs(sol_state_t *state) {
return sol_new_map(state);
}
sol_object_t *sol_new_cstruct_spec(sol_state_t *state, sol_spec_t type) {
ENSURE();
sol_object_t *res = sol_new_cdata(state, NEW(sol_memspec_t), &sol_cstruct_spec_ops);
AS(res->data, sol_memspec_t)->type = type;
return res;
}
void sol_cstruct_add_member(sol_state_t *state, sol_object_t *specs, sol_object_t *key, sol_memtype_t memtype, int offset) {
sol_object_t *spec = sol_new_cstruct_spec(state, SOL_CS_MEMBER);
AS(spec->data, sol_memspec_t)->memtype = memtype;
AS(spec->data, sol_memspec_t)->offset = offset;
sol_map_set(state, spec, key, spec);
sol_obj_free(spec);
}
void sol_cstruct_add_member_name(sol_state_t *state, sol_object_t *specs, char *name, sol_memtype_t memtype, int offset) {
sol_object_t *spec = sol_new_cstruct_spec(state, SOL_CS_MEMBER);
AS(spec->data, sol_memspec_t)->memtype = memtype;
AS(spec->data, sol_memspec_t)->offset = offset;
sol_map_set_name(state, spec, name, spec);
sol_obj_free(spec);
}
void sol_cstruct_add_func(sol_state_t *state, sol_object_t *specs, sol_object_t *key, sol_cfunc_t cfunc) {
sol_object_t *spec = sol_new_cstruct_spec(state, SOL_CS_CFUNC);
AS(spec->data, sol_memspec_t)->cfunc = cfunc;
sol_map_set(state, spec, key, spec);
sol_obj_free(spec);
}
void sol_cstruct_add_func_name(sol_state_t *state, sol_object_t *specs, char *name, sol_cfunc_t cfunc) {
sol_object_t *spec = sol_new_cstruct_spec(state, SOL_CS_CFUNC);
AS(spec->data, sol_memspec_t)->cfunc = cfunc;
sol_map_set_name(state, spec, name, spec);
sol_obj_free(spec);
}
sol_object_t *sol_new_cstruct(sol_state_t *state, void *data, sol_object_t *specs) {
sol_object_t *res = sol_new_cdata(state, NEW(sol_cstruct_t), &sol_cstruct_ops);
AS(res->data, sol_cstruct_t)->data = data;
AS(res->data, sol_cstruct_t)->specs = sol_incref(specs);
return res;
}
sol_object_t *sol_f_cstruct_index(sol_state_t *state, sol_object_t *args) {
sol_object_t *cstructobj = sol_list_get_index(state, args, 0), *idx = sol_list_get_index(state, args, 1);
sol_cstruct_t *cstruct = cstructobj->data;
sol_object_t *specobj = sol_map_get(state, AS(cstruct->data, sol_cstruct_t)->specs, idx), *res = NULL;
sol_memspec_t *spec;
char cbuf[2] = {0, 0};
if(sol_is_none(state, specobj)) {
sol_obj_free(specobj);
sol_obj_free(idx);
sol_obj_free(cstructobj);
return sol_set_error_string(state, "No such CStruct index");
}
spec = specobj->data;
switch(spec->type) {
case SOL_CS_MEMBER:
switch(spec->memtype) {
case SOL_INT:
res = sol_new_int(state, AT(cstruct->data, int, spec->offset));
break;
case SOL_INT8:
res = sol_new_int(state, AT(cstruct->data, int8_t, spec->offset));
break;
case SOL_INT16:
res = sol_new_int(state, AT(cstruct->data, int16_t, spec->offset));
break;
case SOL_INT32:
res = sol_new_int(state, AT(cstruct->data, int32_t, spec->offset));
break;
case SOL_INT64:
res = sol_new_int(state, AT(cstruct->data, int64_t, spec->offset));
break;
case SOL_UINT:
res = sol_new_int(state, AT(cstruct->data, unsigned int, spec->offset));
break;
case SOL_UINT8:
res = sol_new_int(state, AT(cstruct->data, uint8_t, spec->offset));
break;
case SOL_UINT16:
res = sol_new_int(state, AT(cstruct->data, uint16_t, spec->offset));
break;
case SOL_UINT32:
res = sol_new_int(state, AT(cstruct->data, uint32_t, spec->offset));
break;
/*case SOL_UINT64:
res = sol_new_int(state, AT(cstruct->data, uint64_t, spec->offset));
break;*/
case SOL_FLOAT:
res = sol_new_float(state, AT(cstruct->data, float, spec->offset));
break;
case SOL_DOUBLE:
res = sol_new_float(state, AT(cstruct->data, double, spec->offset));
break;
case SOL_CHAR:
cbuf[0] = AT(cstruct->data, char, spec->offset);
res = sol_new_string(state, cbuf);
break;
case SOL_CSTR:
res = sol_new_string(state, AT(cstruct->data, char *, spec->offset));
break;
case SOL_CFUNC:
res = sol_new_cfunc(state, AT(cstruct->data, sol_cfunc_t, spec->offset));
break;
}
break;
case SOL_CS_CFUNC:
res = sol_new_cfunc(state, spec->cfunc);
break;
}
if(!res) res = sol_incref(state->None);
return res;
}
sol_object_t *sol_f_cstruct_setindex(sol_state_t *state, sol_object_t *args) {
sol_object_t *cstructobj = sol_list_get_index(state, args, 0), *idx = sol_list_get_index(state, args, 1), *val = sol_list_get_index(state, args, 2);
sol_cstruct_t *cstruct = cstructobj->data;
sol_object_t *specobj = sol_map_get(state, AS(cstruct->data, sol_cstruct_t)->specs, idx);
sol_memspec_t *spec;
char cbuf[2] = {0, 0};
if(sol_is_none(state, specobj)) {
sol_obj_free(specobj);
sol_obj_free(idx);
sol_obj_free(cstructobj);
return sol_set_error_string(state, "No such CStruct index");
}
spec = specobj->data;
switch(spec->type) {
case SOL_CS_MEMBER:
switch(spec->memtype) {
case SOL_INT:
AT(cstruct->data, int, spec->offset) = sol_cast_int(state, val)->ival;
break;
case SOL_INT8:
AT(cstruct->data, int8_t, spec->offset) = sol_cast_int(state, val)->ival;
break;
case SOL_INT16:
AT(cstruct->data, int16_t, spec->offset) = sol_cast_int(state, val)->ival;
break;
case SOL_INT32:
AT(cstruct->data, int32_t, spec->offset) = sol_cast_int(state, val)->ival;
break;
case SOL_INT64:
AT(cstruct->data, int64_t, spec->offset) = sol_cast_int(state, val)->ival;
break;
case SOL_UINT:
AT(cstruct->data, unsigned int, spec->offset) = sol_cast_int(state, val)->ival;
break;
case SOL_UINT8:
AT(cstruct->data, uint8_t, spec->offset) = sol_cast_int(state, val)->ival;
break;
case SOL_UINT16:
AT(cstruct->data, uint16_t, spec->offset) = sol_cast_int(state, val)->ival;
break;
case SOL_UINT32:
AT(cstruct->data, uint32_t, spec->offset) = sol_cast_int(state, val)->ival;
break;
/*case SOL_UINT64:
AT(cstruct->data, uint64_t, spec->offset) = sol_cast_int(state, val)->ival;
break;*/
case SOL_FLOAT:
AT(cstruct->data, float, spec->offset) = sol_cast_float(state, val)->fval;
break;
case SOL_DOUBLE:
AT(cstruct->data, double, spec->offset) = sol_cast_float(state, val)->fval;
break;
case SOL_CHAR:
AT(cstruct->data, char, spec->offset) = sol_cast_string(state, val)->str[0];
break;
case SOL_CSTR:
AT(cstruct->data, char *, spec->offset) = strdup(sol_cast_string(state, val)->str);
break;
case SOL_CFUNC:
return sol_set_error_string(state, "Can't assign CFunc members");
break;
}
break;
case SOL_CS_CFUNC:
return sol_set_error_string(state, "Can't assign CFunc members");
break;
}
return sol_incref(state->None);
}

19
cdata.h

@ -19,12 +19,20 @@ typedef enum {
SOL_CHAR,
SOL_CSTR,
SOL_CFUNC
} sol_memtype_t
} sol_memtype_t;
typedef enum {
SOL_CS_MEMBER,
SOL_CS_CFUNC
} sol_spec_t;
typedef struct {
sol_memtype_t type;
sol_spec_t type;
union {
int offset;
struct {
sol_memtype_t memtype;
int offset;
};
sol_cfunc_t cfunc;
};
} sol_memspec_t;
@ -35,13 +43,14 @@ typedef struct {
} sol_cstruct_t;
sol_object_t *sol_new_cstruct_specs(sol_state_t *);
void sol_cstruct_add_member(sol_state_t *, sol_object_t *, sol_object_t *, sol_memspec_t, int);
void sol_cstruct_add_member_name(sol_state_t *, sol_object_t *, char *, sol_memspec_t, int);
void sol_cstruct_add_member(sol_state_t *, sol_object_t *, sol_object_t *, sol_memtype_t, int);
void sol_cstruct_add_member_name(sol_state_t *, sol_object_t *, char *, sol_memtype_t, int);
void sol_cstruct_add_func(sol_state_t *, sol_object_t *, sol_object_t *, sol_cfunc_t);
void sol_cstruct_add_func_name(sol_state_t *, sol_object_t *, char *, sol_cfunc_t);
sol_object_t *sol_new_cstruct(sol_state_t *, void *, sol_object_t *);
extern sol_ops_t sol_cstruct_spec_ops;
extern sol_ops_t sol_cstruct_ops;
sol_object_t *sol_f_cstruct_index(sol_state_t *, sol_object_t *);

33
object.c

@ -319,14 +319,37 @@ sol_object_t *sol_list_remove(sol_state_t *state, sol_object_t *list, int idx) {
sol_object_t *sol_list_copy(sol_state_t *state, sol_object_t *list) {
sol_object_t *newls = sol_new_list(state), *cur = list;
sol_object_t *res = newls;
while(cur->lvalue) {
newls->lvalue = sol_incref(cur->lvalue);
if(cur->lnext) {
while(cur) {
if(cur->lvalue) {
newls->lvalue = sol_incref(cur->lvalue);
newls->lnext = sol_alloc_object(state);
if(sol_has_error(state)) return sol_incref(state->None);
newls = newls->lnext;
newls->type = SOL_LCELL;
newls->ops = &(state->LCellOps);
newls->lvalue = NULL;
newls->lnext = NULL;
}
cur = cur->lnext;
}
return res;
}
sol_object_t *sol_list_truncate(sol_state_t *state, sol_object_t *list, int len) {
sol_object_t *newls = sol_new_list(state), *cur = list;
sol_object_t *res = newls;
int i = 0;
while(cur && i<len) {
if(cur->lvalue) {
newls->lvalue = sol_incref(cur->lvalue);
newls->lnext = sol_alloc_object(state);
if(sol_has_error(state)) return sol_incref(state->None);
newls = newls->lnext;
newls->type = SOL_LCELL;
newls->ops = &(state->LCellOps);
newls->lvalue = NULL;
newls->lnext = NULL;
i++;
}
cur = cur->lnext;
}
@ -431,7 +454,7 @@ int sol_map_len(sol_state_t *state, sol_object_t *map) {
return i;
}
sol_object_t *sol_map_submap(sol_state_t *state, sol_object_t *map, sol_object_t *key) {
sol_object_t *sol_map_mcell(sol_state_t *state, sol_object_t *map, sol_object_t *key) {
sol_object_t *list = sol_new_list(state), *res = NULL, *cur = map, *cmp;
sol_list_insert(state, list, 0, key);
while(cur) {
@ -454,7 +477,7 @@ sol_object_t *sol_map_submap(sol_state_t *state, sol_object_t *map, sol_object_t
}
sol_object_t *sol_map_get(sol_state_t *state, sol_object_t *map, sol_object_t *key) {
sol_object_t *submap = sol_map_submap(state, map, key);
sol_object_t *submap = sol_map_mcell(state, map, key);
sol_object_t *res;
if(sol_is_map(submap)) {
res = sol_incref(submap->mval);

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

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

62
parser.y

@ -28,42 +28,41 @@
%%
program:
stmt { *program = AS_ST($1); }
stmt_list { *program = AS_ST($1); }
;
stmt_list:
stmt_list stmt {
stmtlist_node *cur = AS_ST($1)->stmtlist;
while(cur->next) cur = cur->next;
if(cur->stmt) {
cur->next = NEW(stmtlist_node);
cur = cur->next;
}
cur->stmt = $2;
cur->next = NULL;
$$ = $1;
}
| /* empty */ {
$$ = NEW_ST();
AS_ST($$)->type = ST_LIST;
AS_ST($$)->stmtlist = NEW(stmtlist_node);
AS_ST($$)->stmtlist->stmt = NULL;
AS_ST($$)->stmtlist->next = NULL;
}
;
stmt:
expr { $$ = NEW_ST(); AS_ST($$)->type = ST_EXPR; AS_ST($$)->expr = $1; }
| IF expr THEN stmt 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 ELSE stmt 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 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 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; }
| 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; }
| stmt SEMICOLON { $$ = $1; }
| stmt_list { $$ = $1; }
;
stmt_list:
stmt_list stmt {
stmtlist_node *cur = AS_ST($1)->stmtlist;
while(cur->next) cur = cur->next;
cur->next = NEW(stmtlist_node);
cur = cur->next;
cur->stmt = $2;
cur->next = NULL;
$$ = $1;
}
| stmt stmt {
$$ = NEW_ST();
AS_ST($$)->type = ST_LIST;
AS_ST($$)->stmtlist = NEW(stmtlist_node);
AS_ST($$)->stmtlist->stmt = $1;
AS_ST($$)->stmtlist->next = NEW(stmtlist_node);
AS_ST($$)->stmtlist->next->stmt = $2;
AS_ST($$)->stmtlist->next->next = NULL;
}
;
expr:
@ -323,7 +322,7 @@ call_expr:
;
funcdecl_expr:
FUNC IDENT LPAREN ident_list RPAREN opt_stmt END {
FUNC IDENT LPAREN ident_list RPAREN stmt_list END {
$$ = NEW_EX();
AS_EX($$)->type = EX_FUNCDECL;
AS_EX($$)->funcdecl = NEW(funcdecl_node);
@ -331,7 +330,7 @@ funcdecl_expr:
AS_EX($$)->funcdecl->args = $4;
AS_EX($$)->funcdecl->body = $6;
}
| FUNC LPAREN ident_list RPAREN opt_stmt END {
| FUNC LPAREN ident_list RPAREN stmt_list END {
$$ = NEW_EX();
AS_EX($$)->type = EX_FUNCDECL;
AS_EX($$)->funcdecl = NEW(funcdecl_node);
@ -342,11 +341,6 @@ funcdecl_expr:
| index_expr { $$ = $1; }
;
opt_stmt:
stmt { $$ = $1; }
| /* empty */ { $$ = NULL; }
;
index_expr:
expr LBRACKET expr RBRACKET { $$ = NEW_EX(); AS_EX($$)->type = EX_INDEX; AS_EX($$)->index = NEW(index_node); AS_EX($$)->index->expr = $1; AS_EX($$)->index->index = $3; }
| expr DOT IDENT {

11
sol.h

@ -106,6 +106,7 @@ typedef struct sol_tag_state_t {
sol_ops_t MCellOps;
sol_ops_t FuncOps;
sol_ops_t CFuncOps;
sol_object_t *ListFuncs;
} sol_state_t;
// state.c
@ -200,6 +201,13 @@ sol_object_t *sol_f_list_len(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_list_iter(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_list_tostring(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_list_copy(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_list_insert(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_list_remove(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_list_truncate(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_list_map(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_list_filter(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_map_add(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_map_index(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_map_setindex(sol_state_t *, sol_object_t *);
@ -253,13 +261,14 @@ void sol_list_set_index(sol_state_t *, sol_object_t *, int, sol_object_t *);
void sol_list_insert(sol_state_t *, sol_object_t *, int, sol_object_t *);
sol_object_t *sol_list_remove(sol_state_t *, sol_object_t *, int);
sol_object_t *sol_list_copy(sol_state_t *, sol_object_t *);
sol_object_t *sol_list_truncate(sol_state_t *, sol_object_t *, int);
void sol_list_append(sol_state_t *, sol_object_t *, sol_object_t *);
#define sol_list_push(st, ls, obj) sol_list_insert(st, ls, 0, obj);
#define sol_list_pop(st, ls) sol_list_remove(st, ls, 0);
sol_object_t *sol_new_map(sol_state_t *);
int sol_map_len(sol_state_t *, sol_object_t *);
sol_object_t *sol_map_submap(sol_state_t *, sol_object_t *, sol_object_t *);
sol_object_t *sol_map_mcell(sol_state_t *, sol_object_t *, sol_object_t *);
sol_object_t *sol_map_get(sol_state_t *, sol_object_t *, sol_object_t *);
sol_object_t *sol_map_get_name(sol_state_t *, sol_object_t *, char *);
void sol_map_set(sol_state_t *, sol_object_t *, sol_object_t *, sol_object_t *);

8
state.c

@ -135,6 +135,14 @@ int sol_state_init(sol_state_t *state) {
sol_map_set_name(state, iter, "map", sol_new_cfunc(state, sol_f_iter_map));
sol_map_set_name(state, globals, "iter", iter);
sol_obj_free(iter);
state->ListFuncs = sol_new_map(state);
sol_map_set_name(state, state->ListFuncs, "copy", sol_new_cfunc(state, sol_f_list_copy));
sol_map_set_name(state, state->ListFuncs, "insert", sol_new_cfunc(state, sol_f_list_insert));
sol_map_set_name(state, state->ListFuncs, "remove", sol_new_cfunc(state, sol_f_list_remove));
sol_map_set_name(state, state->ListFuncs, "truncate", sol_new_cfunc(state, sol_f_list_truncate));
sol_map_set_name(state, state->ListFuncs, "map", sol_new_cfunc(state, sol_f_list_map));
sol_map_set_name(state, state->ListFuncs, "filter", sol_new_cfunc(state, sol_f_list_filter));
if(sol_has_error(state)) goto cleanup;
// We're all set!

76
test.sol

@ -1,3 +1,9 @@
print('--- Empty functions')
func f() end
print(f())
print('--- While loop')
a = 1
while a < 10 do
@ -94,3 +100,73 @@ end
myiter.i = 1
for i in myiter do print(i) end
print('--- Method calls')
d = {a = func(a, b) print(a, b) end}
d.a(1, 2)
d:a(3)
print('--- Special methods')
d = {__index = func(obj, key) print('Index', obj, key) return key end,
__setindex = func(obj, key, val) print('SetIndex', obj, key, val) end,
__call = func(obj, arg1, arg2) print('Call', obj, arg1, arg2) return arg1 end}
print(d[3], d[5])
d.a = 7
print(d("q", "r"))
e = {a=1, b=2}
d = {__index = e, __setindex = e}
print(d, d.a, d.b)
d.c = 5
d.b = 7
print(d, e)
print('--- Data sharing')
d = {}
e = [1 2 3 4 5]
d.a = e
d.b = e
print(d)
e[2]=7
e[3]="c"
print(d)
d.a:insert(#(d.a), "q")
d.b:remove(1)
d.a[3]="f"
print(d)
print('--- Arithmetic structure operations')
print([1 2 3]+[4 5])
print([1 2 3]*5)
print({a=1 b=2}+{c=3})
print('--- Map/filter')
l = [1 2 3 4 5]
print(l)
l:map(func (i) return i*3 end)
print(l)
l:filter(func (i) return i & 1 end)
print(l)
print('--- Map/filter chain')
print([1 2 3 4 5]:map(func (i) return i * 3 end):filter(func (i) return i & 1 end))
Loading…
Cancel
Save