Browse Source

Sol Part 13: Can It Do That? Can It Explode Twice?

master
Grissess 7 years ago
parent
commit
e1b6598554
  1. 2
      builtins.c
  2. 115
      cdata.c
  3. 34
      cdata.h
  4. 3
      object.c
  5. 8
      runtime.c

2
builtins.c

@ -222,7 +222,7 @@ sol_object_t *sol_f_rawget(sol_state_t *state, sol_object_t *args) {
res = sol_map_get(state, obj, key);
sol_obj_free(key);
sol_obj_free(obj);
return sol_incref(state->None);
return res;
}

115
cdata.c

@ -2,6 +2,7 @@
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#define AS(arg, tp) ((tp *) (arg))
#define AT(loc, tp, off) (*((tp *) ((char *) loc) + off))
@ -9,8 +10,8 @@
#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;
sol_ops_t sol_cstruct_spec_ops;
sol_ops_t sol_cstruct_ops;
void sol_cstruct_init(void) {
sol_ops_init(&sol_cstruct_spec_ops);
@ -28,68 +29,68 @@ sol_object_t *sol_new_cstruct_specs(sol_state_t *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;
AS(res->cdata, 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;
AS(spec->cdata, sol_memspec_t)->memtype = memtype;
AS(spec->cdata, 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;
AS(spec->cdata, sol_memspec_t)->memtype = memtype;
AS(spec->cdata, sol_memspec_t)->offset = offset;
sol_map_set_name(state, spec, name, spec);
sol_obj_free(spec);
}
void sol_cstruct_add_pointer(sol_state_t *state, sol_object_t *specs, sol_object_t *key, sol_object_t *specs, int offset) {
void sol_cstruct_add_pointer(sol_state_t *state, sol_object_t *pspecs, sol_object_t *key, sol_object_t *specs, int offset) {
sol_object_t *spec = sol_new_cstruct_spec(state, SOL_CS_MEMBER);
AS(spec->data, sol_memspec_t)->memtype = SOL_PTR;
AS(spec->data, sol_memspec_t)->offset = offset;
AS(spec->data, sol_memspec_t)->specs = specs;
AS(spec->cdata, sol_memspec_t)->memtype = SOL_MT_PTR;
AS(spec->cdata, sol_memspec_t)->offset = offset;
AS(spec->cdata, sol_memspec_t)->specs = pspecs;
sol_map_set(state, spec, key, spec);
sol_obj_free(spec);
}
void sol_cstruct_add_pointer_name(sol_state_t *state, sol_object_t *specs, char *name, sol_object_t *specs, int offset) {
void sol_cstruct_add_pointer_name(sol_state_t *state, sol_object_t *pspecs, char *name, sol_object_t *specs, int offset) {
sol_object_t *spec = sol_new_cstruct_spec(state, SOL_CS_MEMBER);
AS(spec->data, sol_memspec_t)->memtype = SOL_PTR;
AS(spec->data, sol_memspec_t)->offset = offset;
AS(spec->data, sol_memspec_t)->specs = specs;
AS(spec->cdata, sol_memspec_t)->memtype = SOL_MT_PTR;
AS(spec->cdata, sol_memspec_t)->offset = offset;
AS(spec->cdata, sol_memspec_t)->specs = pspecs;
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;
AS(spec->cdata, 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;
AS(spec->cdata, 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);
AS(res->cdata, sol_cstruct_t)->data = data;
AS(res->cdata, 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_cstruct_t *cstruct = cstructobj->cdata;
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};
@ -99,72 +100,72 @@ sol_object_t *sol_f_cstruct_index(sol_state_t *state, sol_object_t *args) {
sol_obj_free(cstructobj);
return sol_set_error_string(state, "No such CStruct index");
}
spec = specobj->data;
spec = specobj->cdata;
switch(spec->type) {
case SOL_CS_MEMBER:
switch(spec->memtype) {
case SOL_INT:
case SOL_MT_INT:
res = sol_new_int(state, AT(cstruct->data, int, spec->offset));
break;
case SOL_INT8:
case SOL_MT_INT8:
res = sol_new_int(state, AT(cstruct->data, int8_t, spec->offset));
break;
case SOL_INT16:
case SOL_MT_INT16:
res = sol_new_int(state, AT(cstruct->data, int16_t, spec->offset));
break;
case SOL_INT32:
case SOL_MT_INT32:
res = sol_new_int(state, AT(cstruct->data, int32_t, spec->offset));
break;
case SOL_INT64:
case SOL_MT_INT64:
res = sol_new_int(state, AT(cstruct->data, int64_t, spec->offset));
break;
case SOL_UINT:
case SOL_MT_UINT:
res = sol_new_int(state, AT(cstruct->data, unsigned int, spec->offset));
break;
case SOL_UINT8:
case SOL_MT_UINT8:
res = sol_new_int(state, AT(cstruct->data, uint8_t, spec->offset));
break;
case SOL_UINT16:
case SOL_MT_UINT16:
res = sol_new_int(state, AT(cstruct->data, uint16_t, spec->offset));
break;
case SOL_UINT32:
case SOL_MT_UINT32:
res = sol_new_int(state, AT(cstruct->data, uint32_t, spec->offset));
break;
/*case SOL_UINT64:
/*case SOL_MT_UINT64:
res = sol_new_int(state, AT(cstruct->data, uint64_t, spec->offset));
break;*/
case SOL_FLOAT:
case SOL_MT_FLOAT:
res = sol_new_float(state, AT(cstruct->data, float, spec->offset));
break;
case SOL_DOUBLE:
case SOL_MT_DOUBLE:
res = sol_new_float(state, AT(cstruct->data, double, spec->offset));
break;
case SOL_CHAR:
case SOL_MT_CHAR:
cbuf[0] = AT(cstruct->data, char, spec->offset);
res = sol_new_string(state, cbuf);
break;
case SOL_CSTR:
case SOL_MT_CSTR:
res = sol_new_string(state, AT(cstruct->data, char *, spec->offset));
break;
case SOL_CFUNC:
case SOL_MT_CFUNC:
res = sol_new_cfunc(state, AT(cstruct->data, sol_cfunc_t, spec->offset));
break;
case SOL_PTR:
case SOL_MT_PTR:
res = sol_new_cstruct(state, AT(cstruct->data, void *, spec->offset), spec->specs);
break;
}
@ -180,7 +181,7 @@ sol_object_t *sol_f_cstruct_index(sol_state_t *state, sol_object_t *args) {
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_cstruct_t *cstruct = cstructobj->cdata;
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};
@ -190,74 +191,74 @@ sol_object_t *sol_f_cstruct_setindex(sol_state_t *state, sol_object_t *args) {
sol_obj_free(cstructobj);
return sol_set_error_string(state, "No such CStruct index");
}
spec = specobj->data;
spec = specobj->cdata;
switch(spec->type) {
case SOL_CS_MEMBER:
switch(spec->memtype) {
case SOL_INT:
case SOL_MT_INT:
AT(cstruct->data, int, spec->offset) = sol_cast_int(state, val)->ival;
break;
case SOL_INT8:
case SOL_MT_INT8:
AT(cstruct->data, int8_t, spec->offset) = sol_cast_int(state, val)->ival;
break;
case SOL_INT16:
case SOL_MT_INT16:
AT(cstruct->data, int16_t, spec->offset) = sol_cast_int(state, val)->ival;
break;
case SOL_INT32:
case SOL_MT_INT32:
AT(cstruct->data, int32_t, spec->offset) = sol_cast_int(state, val)->ival;
break;
case SOL_INT64:
case SOL_MT_INT64:
AT(cstruct->data, int64_t, spec->offset) = sol_cast_int(state, val)->ival;
break;
case SOL_UINT:
case SOL_MT_UINT:
AT(cstruct->data, unsigned int, spec->offset) = sol_cast_int(state, val)->ival;
break;
case SOL_UINT8:
case SOL_MT_UINT8:
AT(cstruct->data, uint8_t, spec->offset) = sol_cast_int(state, val)->ival;
break;
case SOL_UINT16:
case SOL_MT_UINT16:
AT(cstruct->data, uint16_t, spec->offset) = sol_cast_int(state, val)->ival;
break;
case SOL_UINT32:
case SOL_MT_UINT32:
AT(cstruct->data, uint32_t, spec->offset) = sol_cast_int(state, val)->ival;
break;
/*case SOL_UINT64:
/*case SOL_MT_UINT64:
AT(cstruct->data, uint64_t, spec->offset) = sol_cast_int(state, val)->ival;
break;*/
case SOL_FLOAT:
case SOL_MT_FLOAT:
AT(cstruct->data, float, spec->offset) = sol_cast_float(state, val)->fval;
break;
case SOL_DOUBLE:
case SOL_MT_DOUBLE:
AT(cstruct->data, double, spec->offset) = sol_cast_float(state, val)->fval;
break;
case SOL_CHAR:
case SOL_MT_CHAR:
AT(cstruct->data, char, spec->offset) = sol_cast_string(state, val)->str[0];
break;
case SOL_CSTR:
case SOL_MT_CSTR:
AT(cstruct->data, char *, spec->offset) = strdup(sol_cast_string(state, val)->str);
break;
case SOL_CFUNC:
case SOL_MT_CFUNC:
return sol_set_error_string(state, "Can't assign CFunc members");
break;
case SOL_PTR:
if(!sol_is_cdata(val) || spec->specs != AS(val->data, sol_cstruct_t)->specs)
case SOL_MT_PTR:
if(!sol_is_cdata(val) || spec->specs != AS(val->cdata, sol_cstruct_t)->specs)
return sol_set_error_string(state, "Invalid type for PTR assignment");
AS(cstruct->data, void *, spec->offset) = AS(val->data, sol_cstruct_t)->data;
AT(cstruct->data, void *, spec->offset) = AS(val->cdata, sol_cstruct_t)->data;
}
break;

34
cdata.h

@ -4,22 +4,22 @@
#include "sol.h"
typedef enum {
SOL_INT,
SOL_INT8,
SOL_INT16,
SOL_INT32,
SOL_INT64,
SOL_UINT,
SOL_UINT8,
SOL_UINT16,
SOL_UINT32,
// SOL_UINT64, TODO: Not yet supported
SOL_FLOAT,
SOL_DOUBLE,
SOL_CHAR,
SOL_CSTR,
SOL_CFUNC,
SOL_PTR // Don't use this in add_member--use add_pointer
SOL_MT_INT,
SOL_MT_INT8,
SOL_MT_INT16,
SOL_MT_INT32,
SOL_MT_INT64,
SOL_MT_UINT,
SOL_MT_UINT8,
SOL_MT_UINT16,
SOL_MT_UINT32,
// SOL_MT_UINT64, TODO: Not yet supported
SOL_MT_FLOAT,
SOL_MT_DOUBLE,
SOL_MT_CHAR,
SOL_MT_CSTR,
SOL_MT_CFUNC,
SOL_MT_PTR // Don't use this in add_member--use add_pointer
} sol_memtype_t;
typedef enum {
@ -58,6 +58,6 @@ 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 *);
sol_object_t *sol_f_cstruct_setindex(sol_state_t *, sol_object_t *)
sol_object_t *sol_f_cstruct_setindex(sol_state_t *, sol_object_t *);
#endif

3
object.c

@ -289,7 +289,7 @@ void sol_list_insert(sol_state_t *state, sol_object_t *list, int idx, sol_object
}
sol_object_t *sol_list_remove(sol_state_t *state, sol_object_t *list, int idx) {
sol_object_t *next = list, *prev = NULL, *res, *temp;
sol_object_t *next = list, *prev = NULL, *res;
int i = 0;
if(sol_has_error(state)) return sol_incref(state->None);
if(idx < 0) {
@ -442,6 +442,7 @@ sol_object_t *sol_new_map(sol_state_t *state) {
map->mkey = NULL;
map->mval = NULL;
map->mnext = NULL;
return map;
}
int sol_map_len(sol_state_t *state, sol_object_t *map) {

8
runtime.c

@ -55,6 +55,9 @@ void st_free(stmt_node *stmt) {
ex_free(stmt->ret->ret);
free(stmt->ret);
break;
case ST_CONT: case ST_BREAK:
break; // Make the compiler happy :D
}
free(stmt);
}
@ -160,10 +163,9 @@ void ex_free(expr_node *expr) {
}
sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
sol_object_t *res, *args, *left, *right, *lint, *rint, *value, *scope, *key, *list;
sol_object_t *res, *left, *right, *lint, *rint, *value, *list;
exprlist_node *cure;
assoclist_node *cura;
identlist_node *curi;
if(!expr) return sol_set_error_string(state, "Evaluate NULL expression");
switch(expr->type) {
case EX_LIT:
@ -388,6 +390,8 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
return res;
break;
}
printf("WARNING: Unhandled expression returning None");
return sol_incref(state->None);
}
void sol_exec(sol_state_t *state, stmt_node *stmt) {

Loading…
Cancel
Save