Browse Source

Sol Part 65: WHY IS IT STILL WORKING?!

master
Graham Northup 4 years ago
parent
commit
babcf57409
Signed by: grissess GPG Key ID: 5D000E6F539376FB
  1. 1
      .gitignore
  2. 17
      Makefile
  3. 5
      ast.h
  4. 2
      builtins.c
  5. 325
      lex.yy.c
  6. 10
      object.c
  7. 11044
      parser.output
  8. 1071
      parser.tab.c
  9. 107
      parser.tab.h
  10. 25
      parser.y
  11. 38
      runtime.c
  12. 3
      ser.c
  13. 17
      sol.h
  14. 10
      state.c
  15. 13
      tests/_crasher_tco.sol
  16. 16
      tests/crasher_multiple_loops.sol
  17. 14
      tests/lang_macro.sol
  18. 2
      tokenizer.lex

1
.gitignore

@ -1,6 +1,7 @@
/sol*
!sol_help.txt
*.o
*.a
stdout
.submodule_stamp
*.orig

17
Makefile

@ -1,5 +1,5 @@
override CFLAGS:= -g $(BUILD_DEFINES) $(CFLAGS)
override LDFLAGS:= -lfl -lm -ldl -lreadline $(LDFLAGS)
_CFLAGS= -g $(BUILD_DEFINES) $(CFLAGS)
_LDFLAGS= -lfl -lm -ldl -lreadline $(LDFLAGS)
OBJ= lex.yy.o parser.tab.o dsl/seq.o dsl/list.o dsl/array.o dsl/generic.o astprint.o runtime.o gc.o object.o state.o builtins.o solrun.o ser.o
ifndef CC
@ -19,7 +19,7 @@ ifndef DESTDIR
endif
ifdef NO_HELP
override CFLAGS+= -DNO_HELP
_CFLAGS+= -DNO_HELP
else
OBJ+= sol_help.o
endif
@ -38,7 +38,7 @@ LINKED_VERS:=sol sol$(MAJOR) sol$(MAJOR).$(MINOR)
.PHONY: install install_bin install_bindir install_lib install_libdir uninstall uninstall_bin uninstall_lib all test clean docs
all: dsl $(LINKED_VERS)
all: dsl libsol.a $(LINKED_VERS)
install: install_bindir install_libdir install_bin install_lib
@ -67,9 +67,12 @@ $(LINKED_VERS): sol$(SOL_VER)
rm $@; ln -s $? $@
sol$(SOL_VER): $(OBJ)
$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@
$(CC) $(_CFLAGS) $^ $(_LDFLAGS) -o $@
test: all $(sort $(patsubst tests/%.sol,test_%,$(wildcard tests/*.sol))) $(sort $(patsubst tests/%.sol,testcomp_%,$(wildcard tests/*.sol)))
libsol.a: $(OBJ)
$(AR) rcs $@ $^
test: all $(sort $(patsubst tests/%.sol,test_%,$(filter-out tests/_%,$(wildcard tests/*.sol)))) $(sort $(patsubst tests/%.sol,testcomp_%,$(filter-out tests/_%,$(wildcard tests/*.sol))))
test_%: tests/%.sol
@ -111,7 +114,7 @@ ARCH_INFO: gc.o
$(OBJDUMP) -f $? | perl -n -e '/file format ([^-]+-(.+))$$/ && print "HOST_ARCH:=$$2\nHOST_ELF:=$$1\n"' > $@
%.o: %.c
$(CC) -c -o $@ $? $(CFLAGS)
$(CC) -c -o $@ $? $(_CFLAGS)
%.o: %.txt | ARCH_INFO
$(OBJCOPY) -B i386 -I binary -O $(HOST_ELF) $? $@

5
ast.h

@ -3,6 +3,8 @@
#include "sol.h"
#define FUNC_IS_MACRO 1
#include <stdio.h>
/** Locator structure.
@ -148,6 +150,7 @@ typedef struct {
paramlist_node *params;
expr_node *anno;
stmt_node *body;
unsigned short flags; // FUNC_IS_MACRO
} funcdecl_node;
typedef struct {
@ -294,7 +297,7 @@ typedef enum {
res;\
})
sol_object_t *sol_new_func(sol_state_t *, identlist_node *, stmt_node *, char *, paramlist_node *, expr_node *);
sol_object_t *sol_new_func(sol_state_t *, identlist_node *, stmt_node *, char *, paramlist_node *, expr_node *, unsigned short);
sol_object_t *sol_new_stmtnode(sol_state_t *, stmt_node *);
sol_object_t *sol_new_exprnode(sol_state_t *, expr_node *);

2
builtins.c

@ -535,6 +535,8 @@ sol_object_t *sol_f_debug_scopes(sol_state_t *state, sol_object_t *args) {
sol_object_t *sol_f_debug_getops(sol_state_t *state, sol_object_t *args) {
sol_object_t *obj = sol_list_get_index(state, args, 0), *res = sol_new_map(state);
sol_map_borrow_name(state, res, "name", sol_new_buffer(state, obj->ops->tname, strlen(obj->ops->tname), OWN_NONE, NULL, NULL));
sol_map_borrow_name(state, res, "flags", sol_new_int(state, obj->ops->tflags));
sol_map_borrow_name(state, res, "add", sol_new_cfunc(state, obj->ops->add, "add"));
sol_map_borrow_name(state, res, "sub", sol_new_cfunc(state, obj->ops->sub, "sub"));
sol_map_borrow_name(state, res, "mul", sol_new_cfunc(state, obj->ops->mul, "mul"));

325
lex.yy.c

@ -375,8 +375,8 @@ static void yynoreturn yy_fatal_error ( const char* msg );
(yy_hold_char) = *yy_cp; \
*yy_cp = '\0'; \
(yy_c_buf_p) = yy_cp;
#define YY_NUM_RULES 74
#define YY_END_OF_BUFFER 75
#define YY_NUM_RULES 75
#define YY_END_OF_BUFFER 76
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@ -384,25 +384,25 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
static const flex_int16_t yy_accept[154] =
static const flex_int16_t yy_accept[158] =
{ 0,
0, 0, 75, 74, 73, 35, 74, 69, 24, 27,
74, 63, 64, 22, 20, 68, 21, 65, 23, 2,
66, 67, 52, 41, 53, 71, 71, 71, 71, 60,
61, 29, 71, 71, 71, 71, 71, 71, 71, 71,
71, 71, 71, 71, 71, 71, 58, 28, 59, 30,
73, 62, 73, 0, 51, 0, 3, 31, 47, 0,
4, 26, 44, 42, 0, 43, 45, 1, 2, 57,
54, 50, 55, 56, 71, 71, 71, 71, 49, 71,
71, 71, 12, 71, 71, 71, 71, 71, 5, 11,
71, 71, 71, 34, 71, 71, 71, 71, 48, 33,
73, 62, 70, 46, 0, 72, 1, 71, 71, 71,
32, 71, 71, 71, 18, 71, 10, 71, 71, 25,
36, 71, 71, 71, 71, 71, 19, 38, 71, 71,
7, 71, 13, 71, 71, 6, 37, 71, 40, 16,
71, 71, 39, 71, 71, 9, 71, 8, 14, 15,
71, 17, 0
0, 0, 76, 75, 74, 36, 75, 70, 25, 28,
75, 64, 65, 23, 21, 69, 22, 66, 24, 2,
67, 68, 53, 42, 54, 72, 72, 72, 72, 61,
62, 30, 72, 72, 72, 72, 72, 72, 72, 72,
72, 72, 72, 72, 72, 72, 59, 29, 60, 31,
74, 63, 74, 0, 52, 0, 3, 32, 48, 0,
4, 27, 45, 43, 0, 44, 46, 1, 2, 58,
55, 51, 56, 57, 72, 72, 72, 72, 50, 72,
72, 72, 12, 72, 72, 72, 72, 72, 5, 11,
72, 72, 72, 72, 35, 72, 72, 72, 72, 49,
34, 74, 63, 71, 47, 0, 73, 1, 72, 72,
72, 33, 72, 72, 72, 19, 72, 10, 72, 72,
72, 26, 37, 72, 72, 72, 72, 72, 20, 39,
72, 72, 7, 72, 13, 72, 72, 72, 6, 38,
72, 41, 17, 72, 72, 40, 72, 14, 72, 9,
72, 8, 15, 16, 72, 18, 0
} ;
static const YY_CHAR yy_ec[256] =
@ -447,49 +447,51 @@ static const YY_CHAR yy_meta[53] =
1, 1
} ;
static const flex_int16_t yy_base[158] =
static const flex_int16_t yy_base[162] =
{ 0,
0, 51, 171, 172, 52, 52, 165, 172, 172, 49,
160, 172, 172, 46, 146, 172, 44, 172, 145, 44,
172, 172, 42, 144, 47, 0, 134, 121, 119, 172,
172, 140, 119, 116, 116, 115, 25, 41, 37, 126,
113, 112, 110, 118, 38, 115, 172, 54, 172, 172,
75, 172, 78, 147, 172, 145, 172, 172, 172, 140,
172, 126, 172, 172, 144, 172, 172, 128, 71, 172,
172, 172, 172, 172, 0, 105, 102, 96, 172, 108,
106, 98, 0, 94, 104, 97, 92, 93, 0, 0,
93, 99, 86, 0, 85, 95, 82, 90, 172, 172,
88, 172, 172, 172, 124, 172, 108, 80, 89, 88,
0, 91, 75, 85, 0, 74, 0, 85, 85, 0,
0, 69, 73, 79, 73, 77, 0, 0, 72, 65,
64, 66, 0, 66, 55, 0, 0, 62, 0, 0,
54, 59, 0, 63, 51, 0, 45, 0, 0, 0,
51, 0, 172, 104, 106, 81, 108
0, 51, 175, 176, 52, 52, 169, 176, 176, 49,
164, 176, 176, 46, 150, 176, 44, 176, 149, 44,
176, 176, 42, 148, 47, 0, 138, 125, 123, 176,
176, 144, 123, 120, 120, 119, 25, 41, 37, 130,
44, 117, 115, 123, 39, 120, 176, 55, 176, 176,
79, 176, 83, 152, 176, 150, 176, 176, 176, 145,
176, 131, 176, 176, 149, 176, 176, 133, 62, 176,
176, 176, 176, 176, 0, 110, 107, 101, 176, 113,
111, 103, 0, 99, 109, 102, 97, 98, 0, 0,
98, 105, 103, 90, 0, 89, 99, 86, 94, 176,
176, 88, 176, 176, 176, 128, 176, 112, 84, 93,
92, 0, 95, 79, 89, 0, 78, 0, 89, 89,
76, 0, 0, 72, 76, 82, 76, 80, 0, 0,
75, 75, 74, 69, 0, 69, 59, 57, 0, 0,
65, 0, 0, 57, 61, 0, 65, 0, 53, 0,
47, 0, 0, 0, 58, 0, 176, 105, 107, 90,
109
} ;
static const flex_int16_t yy_def[158] =
static const flex_int16_t yy_def[162] =
{ 0,
153, 1, 153, 153, 153, 153, 154, 153, 153, 153,
155, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153, 153, 156, 156, 156, 156, 153,
153, 153, 156, 156, 156, 156, 156, 156, 156, 156,
156, 156, 156, 156, 156, 156, 153, 153, 153, 153,
153, 153, 153, 153, 153, 154, 153, 153, 153, 155,
153, 153, 153, 153, 157, 153, 153, 153, 153, 153,
153, 153, 153, 153, 156, 156, 156, 156, 153, 156,
156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
156, 156, 156, 156, 156, 156, 156, 156, 153, 153,
153, 153, 153, 153, 157, 153, 153, 156, 156, 156,
156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
156, 156, 0, 153, 153, 153, 153
157, 1, 157, 157, 157, 157, 158, 157, 157, 157,
159, 157, 157, 157, 157, 157, 157, 157, 157, 157,
157, 157, 157, 157, 157, 160, 160, 160, 160, 157,
157, 157, 160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 157, 157, 157, 157,
157, 157, 157, 157, 157, 158, 157, 157, 157, 159,
157, 157, 157, 157, 161, 157, 157, 157, 157, 157,
157, 157, 157, 157, 160, 160, 160, 160, 157, 160,
160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160, 160, 157,
157, 157, 157, 157, 157, 161, 157, 157, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 0, 157, 157, 157,
157
} ;
static const flex_int16_t yy_nxt[225] =
static const flex_int16_t yy_nxt[229] =
{ 0,
4, 5, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
@ -498,27 +500,27 @@ static const flex_int16_t yy_nxt[225] =
41, 42, 43, 44, 26, 45, 26, 46, 47, 48,
49, 50, 51, 53, 53, 54, 58, 62, 65, 68,
52, 69, 70, 71, 84, 66, 85, 63, 73, 74,
59, 86, 89, 55, 96, 99, 101, 53, 90, 53,
53, 97, 75, 87, 102, 152, 68, 88, 69, 101,
53, 151, 150, 149, 148, 147, 146, 102, 145, 144,
143, 142, 141, 100, 56, 56, 60, 60, 105, 105,
140, 139, 138, 137, 136, 135, 134, 133, 132, 131,
130, 129, 128, 127, 126, 107, 106, 125, 124, 123,
122, 121, 120, 119, 118, 117, 116, 115, 114, 113,
112, 111, 110, 109, 108, 107, 106, 104, 61, 57,
103, 98, 95, 94, 93, 92, 91, 83, 82, 81,
80, 79, 78, 77, 76, 72, 67, 64, 61, 57,
153, 3, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153
59, 86, 89, 55, 92, 97, 100, 68, 90, 69,
102, 53, 98, 87, 53, 53, 93, 88, 103, 102,
53, 75, 156, 155, 154, 153, 152, 103, 151, 150,
149, 148, 147, 146, 101, 56, 56, 60, 60, 106,
106, 145, 144, 143, 142, 141, 140, 139, 138, 137,
136, 135, 134, 133, 132, 131, 130, 129, 128, 108,
107, 127, 126, 125, 124, 123, 122, 121, 120, 119,
118, 117, 116, 115, 114, 113, 112, 111, 110, 109,
108, 107, 105, 61, 57, 104, 99, 96, 95, 94,
91, 83, 82, 81, 80, 79, 78, 77, 76, 72,
67, 64, 61, 57, 157, 3, 157, 157, 157, 157,
157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
157, 157, 157, 157, 157, 157, 157, 157
} ;
static const flex_int16_t yy_chk[225] =
static const flex_int16_t yy_chk[229] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@ -527,24 +529,24 @@ static const flex_int16_t yy_chk[225] =
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 2, 5, 5, 6, 10, 14, 17, 20,
2, 20, 23, 23, 37, 17, 37, 14, 25, 25,
10, 38, 39, 6, 45, 48, 51, 51, 39, 53,
53, 45, 156, 38, 51, 151, 69, 38, 69, 101,
101, 147, 145, 144, 142, 141, 138, 101, 135, 134,
132, 131, 130, 48, 154, 154, 155, 155, 157, 157,
129, 126, 125, 124, 123, 122, 119, 118, 116, 114,
113, 112, 110, 109, 108, 107, 105, 98, 97, 96,
95, 93, 92, 91, 88, 87, 86, 85, 84, 82,
81, 80, 78, 77, 76, 68, 65, 62, 60, 56,
54, 46, 44, 43, 42, 41, 40, 36, 35, 34,
33, 32, 29, 28, 27, 24, 19, 15, 11, 7,
3, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153
10, 38, 39, 6, 41, 45, 48, 69, 39, 69,
51, 51, 45, 38, 53, 53, 41, 38, 51, 102,
102, 160, 155, 151, 149, 147, 145, 102, 144, 141,
138, 137, 136, 134, 48, 158, 158, 159, 159, 161,
161, 133, 132, 131, 128, 127, 126, 125, 124, 121,
120, 119, 117, 115, 114, 113, 111, 110, 109, 108,
106, 99, 98, 97, 96, 94, 93, 92, 91, 88,
87, 86, 85, 84, 82, 81, 80, 78, 77, 76,
68, 65, 62, 60, 56, 54, 46, 44, 43, 42,
40, 36, 35, 34, 33, 32, 29, 28, 27, 24,
19, 15, 11, 7, 3, 157, 157, 157, 157, 157,
157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
157, 157, 157, 157, 157, 157, 157, 157
} ;
static yy_state_type yy_last_accepting_state;
@ -621,7 +623,7 @@ static void update_loc(YYLTYPE *yylloc, char *yytext){
#define YY_USER_ACTION update_loc(yylloc, yytext);
#line 624 "lex.yy.c"
#line 626 "lex.yy.c"
/* This is the right way to do it, but it keeps generating token $undefined.
%x STRING
@ -637,7 +639,7 @@ static void update_loc(YYLTYPE *yylloc, char *yytext){
<STRING>. { str_putc(*yytext); }
*/
#line 640 "lex.yy.c"
#line 642 "lex.yy.c"
#define INITIAL 0
@ -878,7 +880,7 @@ YY_DECL
#line 85 "tokenizer.lex"
#line 881 "lex.yy.c"
#line 883 "lex.yy.c"
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
{
@ -906,13 +908,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 154 )
if ( yy_current_state >= 158 )
yy_c = yy_meta[yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
++yy_cp;
}
while ( yy_base[yy_current_state] != 172 );
while ( yy_base[yy_current_state] != 176 );
yy_find_action:
yy_act = yy_accept[yy_current_state];
@ -1003,57 +1005,57 @@ YY_RULE_SETUP
case 14:
YY_RULE_SETUP
#line 112 "tokenizer.lex"
{ return LAMBDA; }
{ return MACRO; }
YY_BREAK
case 15:
YY_RULE_SETUP
#line 114 "tokenizer.lex"
{ return RETURN; }
{ return LAMBDA; }
YY_BREAK
case 16:
YY_RULE_SETUP
#line 116 "tokenizer.lex"
{ return BREAK; }
{ return RETURN; }
YY_BREAK
case 17:
YY_RULE_SETUP
#line 118 "tokenizer.lex"
{ return CONTINUE; }
{ return BREAK; }
YY_BREAK
case 18:
YY_RULE_SETUP
#line 120 "tokenizer.lex"
{ return END; }
{ return CONTINUE; }
YY_BREAK
case 19:
YY_RULE_SETUP
#line 122 "tokenizer.lex"
{ return NONE; }
{ return END; }
YY_BREAK
case 20:
YY_RULE_SETUP
#line 124 "tokenizer.lex"
{ return PLUS; }
{ return NONE; }
YY_BREAK
case 21:
YY_RULE_SETUP
#line 126 "tokenizer.lex"
{ return MINUS; }
{ return PLUS; }
YY_BREAK
case 22:
YY_RULE_SETUP
#line 128 "tokenizer.lex"
{ return STAR; }
{ return MINUS; }
YY_BREAK
case 23:
YY_RULE_SETUP
#line 130 "tokenizer.lex"
{ return SLASH; }
{ return STAR; }
YY_BREAK
case 24:
YY_RULE_SETUP
#line 132 "tokenizer.lex"
{ return PERCENT; }
{ return SLASH; }
YY_BREAK
case 25:
YY_RULE_SETUP
@ -1063,32 +1065,32 @@ YY_RULE_SETUP
case 26:
YY_RULE_SETUP
#line 136 "tokenizer.lex"
{ return DSTAR; }
{ return PERCENT; }
YY_BREAK
case 27:
YY_RULE_SETUP
#line 138 "tokenizer.lex"
{ return BAND; }
{ return DSTAR; }
YY_BREAK
case 28:
YY_RULE_SETUP
#line 140 "tokenizer.lex"
{ return BOR; }
{ return BAND; }
YY_BREAK
case 29:
YY_RULE_SETUP
#line 142 "tokenizer.lex"
{ return BXOR; }
{ return BOR; }
YY_BREAK
case 30:
YY_RULE_SETUP
#line 144 "tokenizer.lex"
{ return BNOT; }
{ return BXOR; }
YY_BREAK
case 31:
YY_RULE_SETUP
#line 146 "tokenizer.lex"
{ return LAND; }
{ return BNOT; }
YY_BREAK
case 32:
YY_RULE_SETUP
@ -1098,7 +1100,7 @@ YY_RULE_SETUP
case 33:
YY_RULE_SETUP
#line 150 "tokenizer.lex"
{ return LOR; }
{ return LAND; }
YY_BREAK
case 34:
YY_RULE_SETUP
@ -1108,7 +1110,7 @@ YY_RULE_SETUP
case 35:
YY_RULE_SETUP
#line 154 "tokenizer.lex"
{ return LNOT; }
{ return LOR; }
YY_BREAK
case 36:
YY_RULE_SETUP
@ -1118,7 +1120,7 @@ YY_RULE_SETUP
case 37:
YY_RULE_SETUP
#line 158 "tokenizer.lex"
{ *yylval = malloc(sizeof(long)); *((long *) *yylval) = 1; return INT; }
{ return LNOT; }
YY_BREAK
case 38:
YY_RULE_SETUP
@ -1128,7 +1130,7 @@ YY_RULE_SETUP
case 39:
YY_RULE_SETUP
#line 162 "tokenizer.lex"
{ *yylval = malloc(sizeof(long)); *((long *) *yylval) = 0; return INT; }
{ *yylval = malloc(sizeof(long)); *((long *) *yylval) = 1; return INT; }
YY_BREAK
case 40:
YY_RULE_SETUP
@ -1138,176 +1140,181 @@ YY_RULE_SETUP
case 41:
YY_RULE_SETUP
#line 166 "tokenizer.lex"
{ return ASSIGN; }
{ *yylval = malloc(sizeof(long)); *((long *) *yylval) = 0; return INT; }
YY_BREAK
case 42:
YY_RULE_SETUP
#line 168 "tokenizer.lex"
{ return ASSIGNPLUS; }
{ return ASSIGN; }
YY_BREAK
case 43:
YY_RULE_SETUP
#line 170 "tokenizer.lex"
{ return ASSIGNMINUS; }
{ return ASSIGNPLUS; }
YY_BREAK
case 44:
YY_RULE_SETUP
#line 172 "tokenizer.lex"
{ return ASSIGNSTAR; }
{ return ASSIGNMINUS; }
YY_BREAK
case 45:
YY_RULE_SETUP
#line 174 "tokenizer.lex"
{ return ASSIGNSLASH; }
{ return ASSIGNSTAR; }
YY_BREAK
case 46:
YY_RULE_SETUP
#line 176 "tokenizer.lex"
{ return ASSIGNDSTAR; }
{ return ASSIGNSLASH; }
YY_BREAK
case 47:
YY_RULE_SETUP
#line 178 "tokenizer.lex"
{ return ASSIGNBAND; }
{ return ASSIGNDSTAR; }
YY_BREAK
case 48:
YY_RULE_SETUP
#line 180 "tokenizer.lex"
{ return ASSIGNBOR; }
{ return ASSIGNBAND; }
YY_BREAK
case 49:
YY_RULE_SETUP
#line 182 "tokenizer.lex"
{ return ASSIGNBXOR; }
{ return ASSIGNBOR; }
YY_BREAK
case 50:
YY_RULE_SETUP
#line 184 "tokenizer.lex"
{ return EQUAL; }
{ return ASSIGNBXOR; }
YY_BREAK
case 51:
YY_RULE_SETUP
#line 186 "tokenizer.lex"
{ return NEQUAL; }
{ return EQUAL; }
YY_BREAK
case 52:
YY_RULE_SETUP
#line 188 "tokenizer.lex"
{ return LESS; }
{ return NEQUAL; }
YY_BREAK
case 53:
YY_RULE_SETUP
#line 190 "tokenizer.lex"
{ return GREATER; }
{ return LESS; }
YY_BREAK
case 54:
YY_RULE_SETUP
#line 192 "tokenizer.lex"
{ return LESSEQ; }
{ return GREATER; }
YY_BREAK
case 55:
YY_RULE_SETUP
#line 194 "tokenizer.lex"
{ return GREATEREQ; }
{ return LESSEQ; }
YY_BREAK
case 56:
YY_RULE_SETUP
#line 196 "tokenizer.lex"
{ return RSHIFT; }
{ return GREATEREQ; }
YY_BREAK
case 57:
YY_RULE_SETUP
#line 198 "tokenizer.lex"
{ return LSHIFT; }
{ return RSHIFT; }
YY_BREAK
case 58:
YY_RULE_SETUP
#line 200 "tokenizer.lex"
{ return LBRACE; }
{ return LSHIFT; }
YY_BREAK
case 59:
YY_RULE_SETUP
#line 202 "tokenizer.lex"
{ return RBRACE; }
{ return LBRACE; }
YY_BREAK
case 60:
YY_RULE_SETUP
#line 204 "tokenizer.lex"
{ return LBRACKET; }
{ return RBRACE; }
YY_BREAK
case 61:
YY_RULE_SETUP
#line 206 "tokenizer.lex"
{ return RBRACKET; }
{ return LBRACKET; }
YY_BREAK
case 62:
YY_RULE_SETUP
#line 208 "tokenizer.lex"
{ return BLPAREN; } /* "Breaking" paren, not allowed to introduce a call_expr */
{ return RBRACKET; }
YY_BREAK
case 63:
YY_RULE_SETUP
#line 210 "tokenizer.lex"
{ return LPAREN; }
{ return BLPAREN; } /* "Breaking" paren, not allowed to introduce a call_expr */
YY_BREAK
case 64:
YY_RULE_SETUP
#line 212 "tokenizer.lex"
{ return RPAREN; }
{ return LPAREN; }
YY_BREAK
case 65:
YY_RULE_SETUP
#line 214 "tokenizer.lex"
{ return DOT; }
{ return RPAREN; }
YY_BREAK
case 66:
YY_RULE_SETUP
#line 216 "tokenizer.lex"
{ return COLON; }
{ return DOT; }
YY_BREAK
case 67:
YY_RULE_SETUP
#line 218 "tokenizer.lex"
{ return SEMICOLON; }
{ return COLON; }
YY_BREAK
case 68:
YY_RULE_SETUP
#line 220 "tokenizer.lex"
{ return COMMA; }
{ return SEMICOLON; }
YY_BREAK
case 69:
YY_RULE_SETUP
#line 222 "tokenizer.lex"
{ return POUND; }
{ return COMMA; }
YY_BREAK
case 70:
YY_RULE_SETUP
#line 224 "tokenizer.lex"
{ return TBANG; }
{ return POUND; }
YY_BREAK
case 71:
YY_RULE_SETUP
#line 226 "tokenizer.lex"
{ *yylval = (void *) strdup(yytext); return IDENT; }
{ return TBANG; }
YY_BREAK
case 72:
/* rule 72 can match eol */
YY_RULE_SETUP
#line 228 "tokenizer.lex"
/* Skip comments */
{ *yylval = (void *) strdup(yytext); return IDENT; }
YY_BREAK
case 73:
/* rule 73 can match eol */
YY_RULE_SETUP
#line 230 "tokenizer.lex"
/* Skip whitespace */
/* Skip comments */
YY_BREAK
case 74:
/* rule 74 can match eol */
YY_RULE_SETUP
#line 232 "tokenizer.lex"
/* Skip whitespace */
YY_BREAK
case 75:
YY_RULE_SETUP
#line 234 "tokenizer.lex"
ECHO;
YY_BREAK
#line 1310 "lex.yy.c"
#line 1317 "lex.yy.c"
case YY_STATE_EOF(INITIAL):
yyterminate();
@ -1605,7 +1612,7 @@ static int yy_get_next_buffer (void)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 154 )
if ( yy_current_state >= 158 )
yy_c = yy_meta[yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
@ -1633,11 +1640,11 @@ static int yy_get_next_buffer (void)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 154 )
if ( yy_current_state >= 158 )
yy_c = yy_meta[yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
yy_is_jam = (yy_current_state == 153);
yy_is_jam = (yy_current_state == 157);
return yy_is_jam ? 0 : yy_current_state;
}
@ -2315,7 +2322,7 @@ void yyfree (void * ptr )
#define YYTABLES_NAME "yytables"
#line 232 "tokenizer.lex"
#line 234 "tokenizer.lex"
int yywrap(void) {

10
object.c

@ -526,6 +526,16 @@ sol_object_t *sol_new_cfunc(sol_state_t *state, sol_cfunc_t cfunc, char *name) {
return res;
}
sol_object_t *sol_new_cmacro(sol_state_t *state, sol_cfunc_t cfunc, char *name) {
sol_object_t *res = sol_alloc_object(state);
res->type = SOL_CMACRO;
res->ops = &(state->CMacroOps);
res->cfunc = cfunc;
res->cfname = name ? strdup(name) : NULL;
sol_init_object(state, res);
return res;
}
sol_object_t *sol_f_cfunc_free(sol_state_t *state, sol_object_t *cfunc) {
free(cfunc->cfname);
return cfunc;

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

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

107
parser.tab.h

@ -54,59 +54,60 @@ extern int yydebug;
IN = 264,
DO = 265,
FUNC = 266,
LAMBDA = 267,
RETURN = 268,
BREAK = 269,
CONTINUE = 270,
END = 271,
NONE = 272,
IDENT = 273,
INT = 274,
FLOAT = 275,
STRING = 276,
PLUS = 277,
MINUS = 278,
STAR = 279,
SLASH = 280,
PERCENT = 281,
DSTAR = 282,
BAND = 283,
BOR = 284,
BXOR = 285,
BNOT = 286,
LAND = 287,
LOR = 288,
LNOT = 289,
ASSIGN = 290,
ASSIGNPLUS = 291,
ASSIGNMINUS = 292,
ASSIGNSTAR = 293,
ASSIGNSLASH = 294,
ASSIGNDSTAR = 295,
ASSIGNBAND = 296,
ASSIGNBOR = 297,
ASSIGNBXOR = 298,
EQUAL = 299,
NEQUAL = 300,
LESS = 301,
GREATER = 302,
LESSEQ = 303,
GREATEREQ = 304,
RSHIFT = 305,
LSHIFT = 306,
LBRACE = 307,
RBRACE = 308,
BLPAREN = 309,
LPAREN = 310,
RPAREN = 311,
LBRACKET = 312,
RBRACKET = 313,
DOT = 314,
COLON = 315,
SEMICOLON = 316,
COMMA = 317,
POUND = 318,
TBANG = 319
MACRO = 267,
LAMBDA = 268,
RETURN = 269,
BREAK = 270,
CONTINUE = 271,
END = 272,
NONE = 273,
IDENT = 274,
INT = 275,
FLOAT = 276,
STRING = 277,
PLUS = 278,
MINUS = 279,
STAR = 280,
SLASH = 281,
PERCENT = 282,
DSTAR = 283,
BAND = 284,
BOR = 285,
BXOR = 286,
BNOT = 287,
LAND = 288,
LOR = 289,
LNOT = 290,
ASSIGN = 291,
ASSIGNPLUS = 292,
ASSIGNMINUS = 293,
ASSIGNSTAR = 294,
ASSIGNSLASH = 295,
ASSIGNDSTAR = 296,
ASSIGNBAND = 297,
ASSIGNBOR = 298,
ASSIGNBXOR = 299,
EQUAL = 300,
NEQUAL = 301,
LESS = 302,
GREATER = 303,
LESSEQ = 304,
GREATEREQ = 305,
RSHIFT = 306,
LSHIFT = 307,
LBRACE = 308,
RBRACE = 309,
BLPAREN = 310,
LPAREN = 311,
RPAREN = 312,
LBRACKET = 313,
RBRACKET = 314,
DOT = 315,
COLON = 316,
SEMICOLON = 317,
COMMA = 318,
POUND = 319,
TBANG = 320
};
#endif

25
parser.y

@ -23,7 +23,7 @@ void yyerror(loc_t *, stmt_node **, char *);
%token IF THEN ELSEIF ELSE
%token WHILE FOR IN DO
%token FUNC LAMBDA RETURN BREAK CONTINUE
%token FUNC MACRO LAMBDA RETURN BREAK CONTINUE
%token END NONE
%token IDENT
%token INT FLOAT STRING
@ -392,6 +392,7 @@ funcdecl_expr:
AS_EX($$)->funcdecl->params = $4;
AS_EX($$)->funcdecl->anno = $6;
AS_EX($$)->funcdecl->body = $7;
AS_EX($$)->funcdecl->flags = 0;
}
| FUNC any_lparen param_list RPAREN maybe_anno stmt_list END {
$$ = NEW_EX();
@ -401,6 +402,27 @@ funcdecl_expr:
AS_EX($$)->funcdecl->params = $3;
AS_EX($$)->funcdecl->anno = $5;
AS_EX($$)->funcdecl->body = $6;
AS_EX($$)->funcdecl->flags = 0;
}
| MACRO IDENT any_lparen param_list RPAREN maybe_anno stmt_list END {
$$ = NEW_EX();
AS_EX($$)->type = EX_FUNCDECL;
AS_EX($$)->funcdecl = NEW(funcdecl_node);
AS_EX($$)->funcdecl->name = $2;
AS_EX($$)->funcdecl->params = $4;
AS_EX($$)->funcdecl->anno = $6;
AS_EX($$)->funcdecl->body = $7;
AS_EX($$)->funcdecl->flags = FUNC_IS_MACRO;
}
| MACRO any_lparen param_list RPAREN maybe_anno stmt_list END {
$$ = NEW_EX();
AS_EX($$)->type = EX_FUNCDECL;
AS_EX($$)->funcdecl = NEW(funcdecl_node);
AS_EX($$)->funcdecl->name = NULL;
AS_EX($$)->funcdecl->params = $3;
AS_EX($$)->funcdecl->anno = $5;
AS_EX($$)->funcdecl->body = $6;
AS_EX($$)->funcdecl->flags = FUNC_IS_MACRO;
}
| LAMBDA any_lparen param_list RPAREN maybe_anno expr END {
$$ = NEW_EX();
@ -413,6 +435,7 @@ funcdecl_expr:
AS_EX($$)->funcdecl->body->type = ST_RET;
AS_EX($$)->funcdecl->body->ret = NEW(ret_node);
AS_EX($$)->funcdecl->body->ret->ret = $6;
AS_EX($$)->funcdecl->flags = 0;
}
| index_expr { $$ = $1; }
;

38
runtime.c

@ -187,6 +187,7 @@ expr_node *ex_copy(expr_node *old) {
new->funcdecl->params = pl_copy(old->funcdecl->params);
new->funcdecl->anno = ex_copy(old->funcdecl->anno);
new->funcdecl->body = st_copy(old->funcdecl->body);
new->funcdecl->flags = old->funcdecl->flags;
break;
case EX_IFELSE:
@ -807,7 +808,11 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
cure = expr->call->args;
while(cure) {
if(cure->expr) {
sol_list_insert(state, list, sol_list_len(state, list), sol_eval_inner(state, cure->expr, jmp));
if(value->ops->tflags & SOL_TF_NO_EVAL_CALL_ARGS) {
sol_list_insert(state, list, sol_list_len(state, list), sol_new_exprnode(state, cure->expr));
} else {
sol_list_insert(state, list, sol_list_len(state, list), sol_eval_inner(state, cure->expr, jmp));
}
}
ERR_CHECK(state);
cure = cure->next;
@ -820,7 +825,7 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
break;
case EX_FUNCDECL:
res = sol_new_func(state, expr->funcdecl->params ? expr->funcdecl->params->args : NULL, expr->funcdecl->body, expr->funcdecl->name, expr->funcdecl->params, expr->funcdecl->anno);
res = sol_new_func(state, expr->funcdecl->params ? expr->funcdecl->params->args : NULL, expr->funcdecl->body, expr->funcdecl->name, expr->funcdecl->params, expr->funcdecl->anno, expr->funcdecl->flags);
ERR_CHECK(state);
if(expr->funcdecl->name) {
sol_state_assign_l_name(state, expr->funcdecl->name, res);
@ -847,13 +852,14 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
break;
case EX_LOOP:
sol_obj_free(state->loopvalue);
state->loopvalue = sol_new_list(state);
left = state->loopvalue;
res = sol_new_list(state);
value = sol_eval_inner(state, expr->loop->cond, jmp);
vint = sol_cast_int(state, value);
while(vint->ival) {
sol_obj_free(value);
sol_obj_free(vint);
state->loopvalue = res;
sol_exec(state, expr->loop->loop);
if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) {
value = sol_incref(state->None);
@ -867,12 +873,13 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
state->sflag = SF_NORMAL;
sol_obj_free(value);
sol_obj_free(vint);
return sol_incref(state->loopvalue);
state->loopvalue = left;
return sol_incref(res);
break;
case EX_ITER:
sol_obj_free(state->loopvalue);
state->loopvalue = sol_new_list(state);
left = state->loopvalue;
res = sol_new_list(state);
value = sol_eval_inner(state, expr->iter->iter, jmp);
if(value->ops->iter && value->ops->iter != sol_f_not_impl) {
list = sol_new_list(state);
@ -893,6 +900,7 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
item = CALL_METHOD(state, iter, call, list);
while(item != state->None) {
sol_state_assign_l_name(state, expr->iter->var, item);
state->loopvalue = res;
sol_exec(state, expr->iter->loop);
sol_obj_free(item);
if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) {
@ -902,12 +910,16 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
state->sflag = SF_NORMAL;
item = CALL_METHOD(state, iter, call, list);
}
if(state->sflag == SF_BREAKING) {
res = state->loopvalue;
}
state->sflag = SF_NORMAL;
sol_obj_free(iter);
sol_obj_free(value);
sol_obj_free(list);
sol_obj_free(item);
return sol_incref(state->loopvalue);
state->loopvalue = left;
return sol_incref(res);
break;
}
printf("WARNING: Unhandled expression (type %d) returning None\n", expr->type);
@ -993,7 +1005,7 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
}
sol_object_t *sol_f_func_call(sol_state_t *state, sol_object_t *args) {
sol_object_t *res, *scope, *value, *key;
sol_object_t *res, *scope, *value, *key, *tmp;
identlist_node *curi;
dsl_seq_iter *iter;
int argcnt = 0;
@ -1003,7 +1015,7 @@ sol_object_t *sol_f_func_call(sol_state_t *state, sol_object_t *args) {
return sol_incref(state->None);
}
value = dsl_seq_iter_at(iter);
if(!value || !sol_is_func(value)) {
if(!value || !(sol_is_func(value) || sol_is_macro(value))) {
printf("WARNING: Function call without function as first parameter\n");
return sol_incref(state->None);
}
@ -1058,7 +1070,7 @@ sol_object_t *sol_f_func_call(sol_state_t *state, sol_object_t *args) {
return res;
}
sol_object_t *sol_new_func(sol_state_t *state, identlist_node *identlist, stmt_node *body, char *name, paramlist_node *params, expr_node *func_anno) {
sol_object_t *sol_new_func(sol_state_t *state, identlist_node *identlist, stmt_node *body, char *name, paramlist_node *params, expr_node *func_anno, unsigned short flags) {
identlist_node *cura;
exprlist_node *cure;
sol_object_t *obj = sol_alloc_object(state);
@ -1069,8 +1081,8 @@ sol_object_t *sol_new_func(sol_state_t *state, identlist_node *identlist, stmt_n
obj->udata = sol_new_map(state);
obj->rest = NULL;
obj->annos = sol_new_map(state);
obj->type = SOL_FUNCTION;
obj->ops = &(state->FuncOps);
obj->type = (flags & FUNC_IS_MACRO ? SOL_MACRO : SOL_FUNCTION);
obj->ops = (flags & FUNC_IS_MACRO ? &(state->MacroOps) : &(state->FuncOps));
if(params) {
obj->rest = params->rest ? strdup(params->rest) : NULL;
cura = params->clkeys;

3
ser.c

@ -160,6 +160,7 @@ void sol_ser_expr(FILE *io, expr_node *ex) {
sol_ser_pl(io, ex->funcdecl->params);
sol_ser_expr(io, ex->funcdecl->anno);
sol_ser_stmt(io, ex->funcdecl->body);
fwrite(&ex->funcdecl->flags, sizeof(unsigned short), 1, io);
break;
case EX_IFELSE:
@ -504,6 +505,8 @@ void *sol_deser(FILE *io) {
AS_EX(obj)->funcdecl->params = sol_deser_checked(io, BC_LIST_PM);
AS_EX(obj)->funcdecl->anno = sol_deser_expr(io);
AS_EX(obj)->funcdecl->body = sol_deser_stmt(io);
fread(&node, sizeof(unsigned short), 1, io);
AS_EX(obj)->funcdecl->flags = (unsigned short) node;
return obj;
case BC_EX_IFELSE:

17
sol.h

@ -10,7 +10,7 @@
#include "dsl/dsl.h"
/** The version of the project, as made available through `debug.version`. */
#define SOL_VERSION "0.4a1"
#define SOL_VERSION "0.5a0"
/** The hexadecimal version of the project, formatted 0xAAIIRPP where:
*
* - AA is the two-digit major version
@ -116,6 +116,8 @@ typedef void (*sol_printfunc_t)(sol_object_t *);
typedef struct {
/** A C-string naming the type, for use by the built-in `type` function. */
char *tname;
/** Some type-specific flags for this type. */
unsigned short tflags;
/** Called with [this, rhs] to perform binary addition ("+"). */
sol_cfunc_t add;
/** Called with [this, rhs] to perform binary subtraction ("-"). */
@ -170,6 +172,11 @@ typedef struct {
sol_cfunc_t free;
} sol_ops_t;
/** Don't eval arguments passed to ops->call; you will get AST expr_nodes
* instead (wrapped up in SOL_EXPR objects). Call sol_eval to evaluate them when
* desired. */
#define SOL_TF_NO_EVAL_CALL_ARGS 1
/** Object types known to Sol.
*
* This is rarely checked and generally only used where necessary, as there is
@ -195,8 +202,12 @@ typedef enum {
SOL_MCELL,
/** The function type, the type of all user-defined functions in Sol. */
SOL_FUNCTION,
/** The macro type, the type of all user-defined macros in Sol. */
SOL_MACRO,
/** The cfunction type, the type of objects wrapping a `sol_cfunc_t`. */
SOL_CFUNCTION,
/** The cfunction type, the type of objects wrapping a `sol_cfunc_t` without evaluating their arguments. */
SOL_CMACRO,
/** The statement type, the type of objects wrapping a `stmt_node`. */
SOL_STMT,
/** The expression type, the type of objects wrapping an `expr_node`. */
@ -431,7 +442,9 @@ typedef struct sol_tag_state_t {
sol_ops_t MapOps; ///< Operations on maps
sol_ops_t MCellOps; ///< Operations on map cells (rarely used)
sol_ops_t FuncOps; ///< Operations on functions
sol_ops_t MacroOps; ///< Operations on macros
sol_ops_t CFuncOps; ///< Operations on C functions
sol_ops_t CMacroOps; ///< Operations on C macros
sol_ops_t ASTNodeOps; ///< Operations on AST nodes
sol_ops_t BufferOps; ///< Operations on buffers
sol_ops_t DyLibOps; ///< Operations on dynamic library objects
@ -921,6 +934,7 @@ sol_object_t *sol_f_stream_open(sol_state_t *, sol_object_t *);
#define sol_is_list(obj) ((obj)->type == SOL_LIST)
#define sol_is_map(obj) ((obj)->type == SOL_MAP || (obj)->type == SOL_MCELL)
#define sol_is_func(obj) ((obj)->type == SOL_FUNCTION)
#define sol_is_macro(obj) ((obj)->type == SOL_MACRO)
#define sol_is_cfunc(obj) ((obj)->type == SOL_CFUNCTION)
#define sol_is_aststmt(obj) ((obj)->type == SOL_STMT)
#define sol_is_astexpr(obj) ((obj)->type == SOL_EXPR)
@ -1089,6 +1103,7 @@ void sol_map_invert(sol_state_t *, sol_object_t *);
// sol_object_t *sol_new_exprnode(sol_state_t *, expr_node *);
sol_object_t *sol_new_cfunc(sol_state_t *, sol_cfunc_t, char *);
sol_object_t *sol_new_cmacro(sol_state_t *, sol_cfunc_t, char *);
sol_object_t *sol_new_cdata(sol_state_t *, void *, sol_ops_t *);
sol_object_t *sol_new_buffer(sol_state_t *, void *, ssize_t, sol_owntype_t, sol_freefunc_t, sol_movefunc_t);

10
state.c

@ -70,6 +70,7 @@ int sol_state_init(sol_state_t *state) {
state->MapOps = state->NullOps;
state->MCellOps = state->NullOps;
state->FuncOps = state->NullOps;
state->MacroOps = state->NullOps;
state->CFuncOps = state->NullOps;
state->ASTNodeOps = state->NullOps;
state->BufferOps = state->NullOps;
@ -158,11 +159,19 @@ int sol_state_init(sol_state_t *state) {
state->FuncOps.tostring = sol_f_func_tostring;
state->FuncOps.free = sol_f_func_free;
state->MacroOps = state->FuncOps; // XXX Hack
state->MacroOps.tname = "macro";
state->MacroOps.tflags = SOL_TF_NO_EVAL_CALL_ARGS;
state->CFuncOps.tname = "cfunction";
state->CFuncOps.call = sol_f_cfunc_call;
state->CFuncOps.tostring = sol_f_cfunc_tostring;
state->CFuncOps.free = sol_f_cfunc_free;
state->CMacroOps = state->CFuncOps;
state->CMacroOps.tname = "cmacro";
state->CMacroOps.tflags = SOL_TF_NO_EVAL_CALL_ARGS;
state->ASTNodeOps.tname = "astnode";
state->ASTNodeOps.call = sol_f_astnode_call;
state->ASTNodeOps.index = sol_f_astnode_index;
@ -864,6 +873,7 @@ sol_object_t *sol_get_stderr(sol_state_t *state) {
void sol_ops_init(sol_ops_t *ops) {
ops->tname = "unknown";
ops->tflags = 0;
ops->add = sol_f_not_impl;
ops->sub = sol_f_not_impl;
ops->mul = sol_f_not_impl;

13
tests/_crasher_tco.sol

@ -0,0 +1,13 @@
execfile("tests/_lib.sol")
func blow_up_stack(n)
return if n > 0 then
1 + blow_up_stack(n - 1)
else
0
end
end
assert_eq(blow_up_stack(5), 5, "blow_up_stack 5 deep")
assert_eq(blow_up_stack(5000), 5000, "blow_up_stack 5000 deep")
assert_eq(blow_up_stack(5000000), 5000000, "blow_up_stack 5000000 deep")

16
tests/crasher_multiple_loops.sol

@ -0,0 +1,16 @@
execfile("tests/_lib.sol")
func rec_tostring(v)
return for i in v do
continue if type(i) == "list" then
rec_tostring(i)
else
tostring(i)
end
end
end
l = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]
q = [ ["1", "2", "3"], ["4", "5", "6"], ["7", "8", "9"] ]
assert_eq(rec_tostring(l), q, "nested continue-map fors")

14
tests/lang_macro.sol

@ -0,0 +1,14 @@
execfile("tests/_lib.sol")
macro shitty_eval(x, y)
--ast.print(x)
return [x(), y()]
end
assert_eq(shitty_eval(3 + 2, 7 + 9), [5, 16], "macro 1")
macro stupid(ex)
return ex({this_var_does_not_exist = 77})
end
assert_eq(stupid(this_var_does_not_exist - 7), 70, "macro 2")

2
tokenizer.lex

@ -109,6 +109,8 @@ do { return DO; }
func { return FUNC; }
macro { return MACRO; }
lambda { return LAMBDA; }
return { return RETURN; }

Loading…
Cancel
Save