浏览代码

Sol Part 25: Introducing the Solterpreter/Viperpreter!

Graham Northup 6 年前
父节点
当前提交
3ec9528c1d
共有 7 个文件被更改,包括 198 次插入24 次删除
  1. 74
    1
      builtins.c
  2. 70
    0
      interp.sol
  3. 0
    21
      object.c
  4. 6
    0
      sol.h
  5. 17
    2
      solrun.c
  6. 8
    0
      state.c
  7. 23
    0
      test.sol

+ 74
- 1
builtins.c 查看文件

@@ -730,8 +730,15 @@ sol_object_t *sol_f_str_len(sol_state_t *state, sol_object_t *args) {
730 730
 }
731 731
 
732 732
 sol_object_t *sol_f_str_index(sol_state_t *state, sol_object_t *args) {
733
-	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);
733
+	sol_object_t *str = sol_list_get_index(state, args, 0), *key = sol_list_get_index(state, args, 1), *idx, *funcs, *res;
734 734
 	char buf[2]={0, 0};
735
+	if(sol_is_string(key)) {
736
+		funcs = sol_get_methods_name(state, "string");
737
+		res = sol_map_get(state, funcs, key);
738
+		sol_obj_free(funcs);
739
+		return res;
740
+	}
741
+	idx = sol_cast_int(state, key);
735 742
 	if(idx->ival>=0 && idx->ival<strlen(str->str)) {
736 743
 		buf[0] = str->str[idx->ival];
737 744
 	}
@@ -772,6 +779,72 @@ sol_object_t *sol_f_str_repr(sol_state_t *state, sol_object_t *args) {
772 779
 	return next;
773 780
 }
774 781
 
782
+sol_object_t *sol_f_str_sub(sol_state_t *state, sol_object_t *args) {
783
+	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);
784
+	sol_object_t *ilow, *ihigh;
785
+	size_t len = strlen(str->str), i;
786
+	char *s;
787
+	if(sol_is_none(state, low)) {
788
+		ilow = sol_new_int(state, 0);
789
+	} else {
790
+		ilow = sol_cast_int(state, low);
791
+	}
792
+	if(sol_is_none(state, high)) {
793
+		ihigh = sol_new_int(state, len);
794
+	} else {
795
+		ihigh = sol_cast_int(state, high);
796
+	}
797
+	sol_obj_free(low);
798
+	sol_obj_free(high);
799
+	if(ilow->ival<0) {
800
+		ilow->ival+=len;
801
+		if(ilow->ival<0) ilow->ival=0;
802
+	}
803
+	if(ilow->ival>len) ilow->ival=len;
804
+	if(ihigh->ival<0) {
805
+		ihigh->ival+=len;
806
+		if(ihigh->ival<0) ihigh->ival=0;
807
+	}
808
+	if(ihigh->ival>len) ihigh->ival=len;
809
+	if(ilow->ival >= ihigh->ival) {
810
+		sol_obj_free(ilow);
811
+		sol_obj_free(ihigh);
812
+		sol_obj_free(str);
813
+		return sol_new_string(state, "");
814
+	}
815
+	s = malloc(ihigh->ival - ilow->ival + 1);
816
+	for(i=ilow->ival; i<ihigh->ival; i++) s[i-ilow->ival] = str->str[i];
817
+	s[ihigh->ival-ilow->ival]='\0';
818
+	sol_obj_free(ihigh);
819
+	sol_obj_free(ilow);
820
+	sol_obj_free(str);
821
+	return sol_new_string(state, s);
822
+}
823
+
824
+sol_object_t *sol_f_str_split(sol_state_t *state, sol_object_t *args) {
825
+	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);
826
+	sol_object_t *res = sol_new_list(state), *opart;
827
+	char *s = strdup(str->str);
828
+	char *part = strtok(s, stok->str);
829
+	sol_obj_free(tok);
830
+	sol_obj_free(str);
831
+	if(!part) {
832
+		sol_obj_free(res);
833
+		sol_obj_free(stok);
834
+		return sol_incref(state->None);
835
+	}
836
+	opart = sol_new_string(state, part);
837
+	sol_list_insert(state, res, 0, opart);
838
+	sol_obj_free(opart);
839
+	while(part = strtok(NULL, stok->str)) {
840
+		opart = sol_new_string(state, part);
841
+		sol_list_insert(state, res, sol_list_len(state, res), opart);
842
+		sol_obj_free(opart);
843
+	}
844
+	sol_obj_free(stok);
845
+	return res;
846
+}
847
+
775 848
 sol_object_t *sol_f_list_add(sol_state_t *state, sol_object_t *args) {
776 849
 	sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *ls;
777 850
 	if(!sol_is_list(b)) {

+ 70
- 0
interp.sol 查看文件

@@ -0,0 +1,70 @@
1
+-- The Solterpreter! A simple command-line interface for the compiler.
2
+
3
+print('Solterpreter/Viperpreter v0.1')
4
+print('(Runtime version ', debug.version, ')')
5
+
6
+__interp = {
7
+	running = 1,
8
+	buffer = '',
9
+	ps1 = '>>> ',
10
+	ps2 = '... ',
11
+	stmt_stack=0,
12
+}
13
+
14
+func exit()
15
+	__interp.running=0
16
+end
17
+
18
+quit = exit
19
+
20
+while __interp.running do
21
+	if #__interp.buffer then
22
+		io.stdout << __interp.ps2
23
+	else
24
+		io.stdout << __interp.ps1
25
+	end
26
+	__interp.line = io.stdin:read(io.LINE)
27
+	__interp.line = __interp.line:sub(0, -1)
28
+	--prepr(__interp.line)
29
+	if (__interp.line:sub(-4, None)=="then") then
30
+		__interp.buffer+=__interp.line+" "
31
+		__interp.stmt_stack+=1
32
+	else
33
+		if (__interp.line:sub(-2, None)=="do") then
34
+			__interp.buffer+=__interp.line+" "
35
+			__interp.stmt_stack-=1
36
+		else
37
+			if __interp.line:sub(-1, None)=="\" then
38
+				__interp.buffer+=__interp.line:sub(0, -1)+" "
39
+			else
40
+				__interp.buffer+=__interp.line+" "
41
+				if __interp.line:sub(-3, None)=="end" then
42
+					__interp.stmt_stack-=1
43
+				end
44
+				if __interp.stmt_stack<=0 then
45
+					__interp.stmt_stack=0
46
+					__interp.program = try(parse, __interp.buffer)
47
+					if !__interp.program[0] then
48
+						print('Syntax error')
49
+					else
50
+						if __interp.program[1].stmtlist[0].type == ast.ST_EXPR then
51
+							__interp.program[1] = __interp.program[1].stmtlist[0].expr
52
+							__interp.isexpr = 1
53
+						else
54
+							__interp.isexpr = 0
55
+						end
56
+						__interp.result = try(__interp.program[1])
57
+						if !__interp.result[0] then
58
+							print(__interp.result[1])
59
+						else
60
+							if __interp.isexpr then
61
+								prepr(__interp.result[1])
62
+							end
63
+						end
64
+					end
65
+					__interp.buffer=''
66
+				end
67
+			end
68
+		end
69
+	end
70
+end

+ 0
- 21
object.c 查看文件

@@ -100,10 +100,6 @@ void sol_obj_release(sol_object_t *obj) {
100 100
 
101 101
 sol_object_t *sol_new_int(sol_state_t *state, long i) {
102 102
 	sol_object_t *res = sol_alloc_object(state);
103
-	if(sol_has_error(state)) {
104
-		sol_obj_free(res);
105
-		return sol_incref(state->None);
106
-	}
107 103
 	res->type = SOL_INTEGER;
108 104
 	res->ival = i;
109 105
 	res->ops = &(state->IntOps);
@@ -113,10 +109,6 @@ sol_object_t *sol_new_int(sol_state_t *state, long i) {
113 109
 
114 110
 sol_object_t *sol_new_float(sol_state_t *state, double f) {
115 111
 	sol_object_t *res = sol_alloc_object(state);
116
-	if(sol_has_error(state)) {
117
-		sol_obj_free(res);
118
-		return sol_incref(state->None);
119
-	}
120 112
 	res->type = SOL_FLOAT;
121 113
 	res->fval = f;
122 114
 	res->ops = &(state->FloatOps);
@@ -126,10 +118,6 @@ sol_object_t *sol_new_float(sol_state_t *state, double f) {
126 118
 
127 119
 sol_object_t *sol_new_string(sol_state_t *state, const char *s) {
128 120
 	sol_object_t *res = sol_alloc_object(state);
129
-	if(sol_has_error(state)) {
130
-		sol_obj_free(res);
131
-		return sol_incref(state->None);
132
-	}
133 121
 	res->type = SOL_STRING;
134 122
 	res->str = strdup(s);
135 123
 	if(!res->str) {
@@ -171,10 +159,6 @@ sol_object_t *sol_f_str_free(sol_state_t *state, sol_object_t *obj) {
171 159
 
172 160
 sol_object_t *sol_new_list(sol_state_t *state) {
173 161
 	sol_object_t *res = sol_alloc_object(state);
174
-	if(sol_has_error(state)) {
175
-		sol_obj_free(res);
176
-		return sol_incref(state->None);
177
-	}
178 162
 	res->type = SOL_LIST;
179 163
 	res->seq = dsl_seq_new_array(NULL, &(state->obfuncs));
180 164
 	res->ops = &(state->ListOps);
@@ -184,10 +168,6 @@ sol_object_t *sol_new_list(sol_state_t *state) {
184 168
 
185 169
 sol_object_t *sol_list_from_seq(sol_state_t *state, dsl_seq *seq) {
186 170
 	sol_object_t *res = sol_alloc_object(state);
187
-	if(sol_has_error(state)) {
188
-		sol_obj_free(res);
189
-		return sol_incref(state->None);
190
-	}
191 171
 	res->type = SOL_LIST;
192 172
 	res->seq = seq;
193 173
 	res->ops = &(state->ListOps);
@@ -309,7 +289,6 @@ int sol_validate_list(sol_state_t *state, sol_object_t *list) {
309 289
 
310 290
 sol_object_t *sol_new_map(sol_state_t *state) {
311 291
     sol_object_t *map = sol_alloc_object(state);
312
-    if(sol_has_error(state)) return sol_incref(state->None);
313 292
     map->type = SOL_MAP;
314 293
     map->ops = &(state->MapOps);
315 294
     map->seq = dsl_seq_new_array(NULL, &(state->obfuncs));

+ 6
- 0
sol.h 查看文件

@@ -8,6 +8,9 @@
8 8
 #include <stdio.h>
9 9
 #include "dsl/dsl.h"
10 10
 
11
+#define VERSION "0.1a0"
12
+#define HEXVER 0x0001A00
13
+
11 14
 // Forward declarations:
12 15
 struct sol_tag_object_t;
13 16
 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 *);
288 291
 sol_object_t *sol_f_str_tostring(sol_state_t *, sol_object_t *);
289 292
 sol_object_t *sol_f_str_repr(sol_state_t *, sol_object_t *);
290 293
 
294
+sol_object_t *sol_f_str_sub(sol_state_t *, sol_object_t *);
295
+sol_object_t *sol_f_str_split(sol_state_t *, sol_object_t *);
296
+
291 297
 sol_object_t *sol_f_list_add(sol_state_t *, sol_object_t *);
292 298
 sol_object_t *sol_f_list_mul(sol_state_t *, sol_object_t *);
293 299
 sol_object_t *sol_f_list_index(sol_state_t *, sol_object_t *);

+ 17
- 2
solrun.c 查看文件

@@ -7,6 +7,7 @@ int main(int argc, char **argv) {
7 7
     sol_state_t state;
8 8
     char *c;
9 9
     int printtree = 0;
10
+	FILE *prgstream = stdin;
10 11
 
11 12
     if(argc>1) {
12 13
         c = argv[1];
@@ -19,12 +20,26 @@ int main(int argc, char **argv) {
19 20
                 case 't':
20 21
                     printtree = 1;
21 22
                     break;
23
+					
24
+				case 'r':
25
+					if(argc<2) {
26
+						printf("r option requires file\n");
27
+						return 1;
28
+					}
29
+					prgstream = fopen(argv[2], "r");
22 30
             }
23 31
             c++;
24 32
         }
25 33
     }
26
-
27
-    program = sol_compile_file(stdin);
34
+    
35
+    if(!prgstream) {
36
+		printf("No input program (check filenames)\n");
37
+		return 1;
38
+	}
39
+
40
+    program = sol_compile_file(prgstream);
41
+	
42
+	if(prgstream!=stdin) fclose(prgstream);
28 43
 
29 44
     if(printtree) st_print(program);
30 45
 

+ 8
- 0
state.c 查看文件

@@ -186,6 +186,8 @@ int sol_state_init(sol_state_t *state) {
186 186
 	sol_map_set_name(state, mod, "globals", sol_new_cfunc(state, sol_f_debug_globals));
187 187
 	sol_map_set_name(state, mod, "locals", sol_new_cfunc(state, sol_f_debug_locals));
188 188
 	sol_map_set_name(state, mod, "scopes", sol_new_cfunc(state, sol_f_debug_scopes));
189
+	sol_map_set_name(state, mod, "version", sol_new_string(state, VERSION));
190
+	sol_map_set_name(state, mod, "hexversion", sol_new_int(state, HEXVER));
189 191
 	sol_register_module_name(state, "debug", mod);
190 192
 	sol_obj_free(mod);
191 193
 	
@@ -361,6 +363,12 @@ int sol_state_init(sol_state_t *state) {
361 363
 	sol_register_methods_name(state, "stream", meths);
362 364
 	sol_obj_free(meths);
363 365
 	
366
+	meths = sol_new_map(state);
367
+	sol_map_set_name(state, meths, "sub", sol_new_cfunc(state, sol_f_str_sub));
368
+	sol_map_set_name(state, meths, "split", sol_new_cfunc(state, sol_f_str_split));
369
+	sol_register_methods_name(state, "string", meths);
370
+	sol_obj_free(meths);
371
+	
364 372
 	if(sol_has_error(state)) goto cleanup;
365 373
 
366 374
 	// We're all set!

+ 23
- 0
test.sol 查看文件

@@ -368,4 +368,27 @@ print('...restored.')
368 368
 print('Output was:')
369 369
 prepr(io.open('stdout', io.MODE_READ):read(io.ALL))
370 370
 
371
+print('--- Substrings')
372
+
373
+s = 'This is a test!'
374
+prepr(s)
375
+prepr(s:sub(1, -1))
376
+prepr(s:sub(3, -3))
377
+prepr(s:sub(3, 5))
378
+prepr(s:sub(3, 11))
379
+prepr(s:sub(-1000, -1000))
380
+
381
+print('--- Splitting')
382
+s = 'This is a test!'
383
+prepr(s)
384
+prepr(s:split(' '))
385
+prepr(s:split('i'))
386
+prepr(s:split('0'))
387
+prepr(s:split('aeiou'))
388
+
389
+l = s:split(' ')
390
+for i in l do
391
+	prepr(i, type(i))
392
+end
393
+
371 394
 print('--- All done!')

正在加载...
取消
保存