Browse Source

Sol Part 25: Introducing the Solterpreter/Viperpreter!

master
Graham Northup 7 years ago
parent
commit
3ec9528c1d
  1. 75
      builtins.c
  2. 70
      interp.sol
  3. 21
      object.c
  4. 6
      sol.h
  5. 19
      solrun.c
  6. 8
      state.c
  7. 23
      test.sol

75
builtins.c

@ -730,8 +730,15 @@ sol_object_t *sol_f_str_len(sol_state_t *state, sol_object_t *args) {
}
sol_object_t *sol_f_str_index(sol_state_t *state, sol_object_t *args) {
sol_object_t *str = sol_list_get_index(state, args, 0), *key = sol_list_get_index(state, args, 1), *idx = sol_cast_int(state, key);
sol_object_t *str = sol_list_get_index(state, args, 0), *key = sol_list_get_index(state, args, 1), *idx, *funcs, *res;
char buf[2]={0, 0};
if(sol_is_string(key)) {
funcs = sol_get_methods_name(state, "string");
res = sol_map_get(state, funcs, key);
sol_obj_free(funcs);
return res;
}
idx = sol_cast_int(state, key);
if(idx->ival>=0 && idx->ival<strlen(str->str)) {
buf[0] = str->str[idx->ival];
}
@ -772,6 +779,72 @@ sol_object_t *sol_f_str_repr(sol_state_t *state, sol_object_t *args) {
return next;
}
sol_object_t *sol_f_str_sub(sol_state_t *state, sol_object_t *args) {
sol_object_t *str = sol_list_get_index(state, args, 0), *low = sol_list_get_index(state, args, 1), *high = sol_list_get_index(state, args, 2);
sol_object_t *ilow, *ihigh;
size_t len = strlen(str->str), i;
char *s;
if(sol_is_none(state, low)) {
ilow = sol_new_int(state, 0);
} else {
ilow = sol_cast_int(state, low);
}
if(sol_is_none(state, high)) {
ihigh = sol_new_int(state, len);
} else {
ihigh = sol_cast_int(state, high);
}
sol_obj_free(low);
sol_obj_free(high);
if(ilow->ival<0) {
ilow->ival+=len;
if(ilow->ival<0) ilow->ival=0;
}
if(ilow->ival>len) ilow->ival=len;
if(ihigh->ival<0) {
ihigh->ival+=len;
if(ihigh->ival<0) ihigh->ival=0;
}
if(ihigh->ival>len) ihigh->ival=len;
if(ilow->ival >= ihigh->ival) {
sol_obj_free(ilow);
sol_obj_free(ihigh);
sol_obj_free(str);
return sol_new_string(state, "");
}
s = malloc(ihigh->ival - ilow->ival + 1);
for(i=ilow->ival; i<ihigh->ival; i++) s[i-ilow->ival] = str->str[i];
s[ihigh->ival-ilow->ival]='\0';
sol_obj_free(ihigh);
sol_obj_free(ilow);
sol_obj_free(str);
return sol_new_string(state, s);
}
sol_object_t *sol_f_str_split(sol_state_t *state, sol_object_t *args) {
sol_object_t *str = sol_list_get_index(state, args, 0), *tok = sol_list_get_index(state, args, 1), *stok = sol_cast_string(state, tok);
sol_object_t *res = sol_new_list(state), *opart;
char *s = strdup(str->str);
char *part = strtok(s, stok->str);
sol_obj_free(tok);
sol_obj_free(str);
if(!part) {
sol_obj_free(res);
sol_obj_free(stok);
return sol_incref(state->None);
}
opart = sol_new_string(state, part);
sol_list_insert(state, res, 0, opart);
sol_obj_free(opart);
while(part = strtok(NULL, stok->str)) {
opart = sol_new_string(state, part);
sol_list_insert(state, res, sol_list_len(state, res), opart);
sol_obj_free(opart);
}
sol_obj_free(stok);
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)) {

70
interp.sol

@ -0,0 +1,70 @@
-- The Solterpreter! A simple command-line interface for the compiler.
print('Solterpreter/Viperpreter v0.1')
print('(Runtime version ', debug.version, ')')
__interp = {
running = 1,
buffer = '',
ps1 = '>>> ',
ps2 = '... ',
stmt_stack=0,
}
func exit()
__interp.running=0
end
quit = exit
while __interp.running do
if #__interp.buffer then
io.stdout << __interp.ps2
else
io.stdout << __interp.ps1
end
__interp.line = io.stdin:read(io.LINE)
__interp.line = __interp.line:sub(0, -1)
--prepr(__interp.line)
if (__interp.line:sub(-4, None)=="then") then
__interp.buffer+=__interp.line+" "
__interp.stmt_stack+=1
else
if (__interp.line:sub(-2, None)=="do") then
__interp.buffer+=__interp.line+" "
__interp.stmt_stack-=1
else
if __interp.line:sub(-1, None)=="\" then
__interp.buffer+=__interp.line:sub(0, -1)+" "
else
__interp.buffer+=__interp.line+" "
if __interp.line:sub(-3, None)=="end" then
__interp.stmt_stack-=1
end
if __interp.stmt_stack<=0 then
__interp.stmt_stack=0
__interp.program = try(parse, __interp.buffer)
if !__interp.program[0] then
print('Syntax error')
else
if __interp.program[1].stmtlist[0].type == ast.ST_EXPR then
__interp.program[1] = __interp.program[1].stmtlist[0].expr
__interp.isexpr = 1
else
__interp.isexpr = 0
end
__interp.result = try(__interp.program[1])
if !__interp.result[0] then
print(__interp.result[1])
else
if __interp.isexpr then
prepr(__interp.result[1])
end
end
end
__interp.buffer=''
end
end
end
end
end

21
object.c

@ -100,10 +100,6 @@ void sol_obj_release(sol_object_t *obj) {
sol_object_t *sol_new_int(sol_state_t *state, long i) {
sol_object_t *res = sol_alloc_object(state);
if(sol_has_error(state)) {
sol_obj_free(res);
return sol_incref(state->None);
}
res->type = SOL_INTEGER;
res->ival = i;
res->ops = &(state->IntOps);
@ -113,10 +109,6 @@ sol_object_t *sol_new_int(sol_state_t *state, long i) {
sol_object_t *sol_new_float(sol_state_t *state, double f) {
sol_object_t *res = sol_alloc_object(state);
if(sol_has_error(state)) {
sol_obj_free(res);
return sol_incref(state->None);
}
res->type = SOL_FLOAT;
res->fval = f;
res->ops = &(state->FloatOps);
@ -126,10 +118,6 @@ sol_object_t *sol_new_float(sol_state_t *state, double f) {
sol_object_t *sol_new_string(sol_state_t *state, const char *s) {
sol_object_t *res = sol_alloc_object(state);
if(sol_has_error(state)) {
sol_obj_free(res);
return sol_incref(state->None);
}
res->type = SOL_STRING;
res->str = strdup(s);
if(!res->str) {
@ -171,10 +159,6 @@ sol_object_t *sol_f_str_free(sol_state_t *state, sol_object_t *obj) {
sol_object_t *sol_new_list(sol_state_t *state) {
sol_object_t *res = sol_alloc_object(state);
if(sol_has_error(state)) {
sol_obj_free(res);
return sol_incref(state->None);
}
res->type = SOL_LIST;
res->seq = dsl_seq_new_array(NULL, &(state->obfuncs));
res->ops = &(state->ListOps);
@ -184,10 +168,6 @@ sol_object_t *sol_new_list(sol_state_t *state) {
sol_object_t *sol_list_from_seq(sol_state_t *state, dsl_seq *seq) {
sol_object_t *res = sol_alloc_object(state);
if(sol_has_error(state)) {
sol_obj_free(res);
return sol_incref(state->None);
}
res->type = SOL_LIST;
res->seq = seq;
res->ops = &(state->ListOps);
@ -309,7 +289,6 @@ int sol_validate_list(sol_state_t *state, sol_object_t *list) {
sol_object_t *sol_new_map(sol_state_t *state) {
sol_object_t *map = sol_alloc_object(state);
if(sol_has_error(state)) return sol_incref(state->None);
map->type = SOL_MAP;
map->ops = &(state->MapOps);
map->seq = dsl_seq_new_array(NULL, &(state->obfuncs));

6
sol.h

@ -8,6 +8,9 @@
#include <stdio.h>
#include "dsl/dsl.h"
#define VERSION "0.1a0"
#define HEXVER 0x0001A00
// Forward declarations:
struct sol_tag_object_t;
typedef struct sol_tag_object_t sol_object_t;
@ -288,6 +291,9 @@ sol_object_t *sol_f_str_tofloat(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_str_tostring(sol_state_t *, sol_object_t *);
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_list_add(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_list_mul(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_list_index(sol_state_t *, sol_object_t *);

19
solrun.c

@ -7,6 +7,7 @@ int main(int argc, char **argv) {
sol_state_t state;
char *c;
int printtree = 0;
FILE *prgstream = stdin;
if(argc>1) {
c = argv[1];
@ -19,12 +20,26 @@ int main(int argc, char **argv) {
case 't':
printtree = 1;
break;
case 'r':
if(argc<2) {
printf("r option requires file\n");
return 1;
}
prgstream = fopen(argv[2], "r");
}
c++;
}
}
program = sol_compile_file(stdin);
if(!prgstream) {
printf("No input program (check filenames)\n");
return 1;
}
program = sol_compile_file(prgstream);
if(prgstream!=stdin) fclose(prgstream);
if(printtree) st_print(program);

8
state.c

@ -186,6 +186,8 @@ int sol_state_init(sol_state_t *state) {
sol_map_set_name(state, mod, "globals", sol_new_cfunc(state, sol_f_debug_globals));
sol_map_set_name(state, mod, "locals", sol_new_cfunc(state, sol_f_debug_locals));
sol_map_set_name(state, mod, "scopes", sol_new_cfunc(state, sol_f_debug_scopes));
sol_map_set_name(state, mod, "version", sol_new_string(state, VERSION));
sol_map_set_name(state, mod, "hexversion", sol_new_int(state, HEXVER));
sol_register_module_name(state, "debug", mod);
sol_obj_free(mod);
@ -361,6 +363,12 @@ int sol_state_init(sol_state_t *state) {
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_register_methods_name(state, "string", meths);
sol_obj_free(meths);
if(sol_has_error(state)) goto cleanup;
// We're all set!

23
test.sol

@ -368,4 +368,27 @@ print('...restored.')
print('Output was:')
prepr(io.open('stdout', io.MODE_READ):read(io.ALL))
print('--- Substrings')
s = 'This is a test!'
prepr(s)
prepr(s:sub(1, -1))
prepr(s:sub(3, -3))
prepr(s:sub(3, 5))
prepr(s:sub(3, 11))
prepr(s:sub(-1000, -1000))
print('--- Splitting')
s = 'This is a test!'
prepr(s)
prepr(s:split(' '))
prepr(s:split('i'))
prepr(s:split('0'))
prepr(s:split('aeiou'))
l = s:split(' ')
for i in l do
prepr(i, type(i))
end
print('--- All done!')
Loading…
Cancel
Save