The unified diff between revisions [9a6e8df1..] and [a81fe555..] is displayed below. It can also be downloaded as a raw diff.
# # old_revision [9a6e8df1d6b102f467702e274d53d90f9151e2c8] # new_revision [a81fe5550c21fa983b4e344e07c29b9cecdf75ea] # # patch "src/lsc/ast.c" # from [38d7a1613ebd1088ccb91c4fc2c7c711467cdd57] # to [d0c7066749da60adc317b58c4630de00a072a23f] # # patch "src/lsc/ast.h" # from [3c28d1b6a01e8e99c8f9485c9771e5f9df66ec83] # to [c16257876c942379840ba94428e4bbbc807d8216] # # patch "src/lsc/codegen.c" # from [3f17dcc09e552288f4a68b0ac58692cffd524364] # to [59287d90158eaceceb9a87f9fe6f6c45059c6cb6] # # patch "src/lsc/lexer.l" # from [88be4de3325822fc6a95e81cc8c615a6c70078bf] # to [abb8ad18ba69e18853d003ba9da3ab968f58d165] # # patch "src/lsc/parser.y" # from [a3d3372576329c2dc4221d54c0a05238eb86dece] # to [2e92a218e99f7522cbd4a48694ec2202d575e0d2] # # patch "src/lsc/types.h" # from [0934f3373a49335fb48fc8fb0d9be2350c843533] # to [b169b733d6297c1e15359d339d187ae7e5798f9b] # # patch "src/lsi/Makefile" # from [609a07c3b2f5a6dcc33cb70112821fa46ab8ade0] # to [78a1f906a0569af4ace0697000ac5411211fcc1c] # # patch "src/lsi/abi.h" # from [f5ff3bd7144f8020da012ea0158aa51d862f888e] # to [0553ade9748fed1e6808e874fa67020a6dd52a22] # # patch "src/lsi/abispec" # from [e8cad560a662c1abc9da835eedd7dddafa77d03f] # to [14bb48cc77b6f36777d424e8a354f629082b14e8] # # patch "src/lsi/makeabi" # from [af04da9852be189b121ae5a7e48a4664afc10c7d] # to [54d8bf7ee907e67849843b113a8c6f5039ec020b] # # patch "src/lsi/mouse.c" # from [410738f63d15db286b591fff6040fcdfe9e1cfa6] # to [51f025fd4be11edf4936c00a3316e4d1ee31b9a5] # # patch "src/lsi/plugins.c" # from [d1249e7348b4b02e2405e3374b7e6609ff982875] # to [f3e7cb50a5258da029d27c67f148fba7845fc552] # # patch "src/lsi/vm.c" # from [0d1a3539301653c5f5cad4792072a3f87ee17d29] # to [c29bc86ce0d4170f8a0229735384ea9eea76763f] # ============================================================ --- src/lsc/ast.c 38d7a1613ebd1088ccb91c4fc2c7c711467cdd57 +++ src/lsc/ast.c d0c7066749da60adc317b58c4630de00a072a23f @@ -110,6 +110,21 @@ ast *make_fndefint(char *identifier, lon return elem; } +ast *make_fndefint_v(char *identifier, long num) +{ + ast *elem = safe_malloc(sizeof(ast)); + ast_list *list = NULL; + + elem->tag = node_ast; + elem->info.node.tag = kind_fndefint_v; + list = make_list(make_integer(num), list); + list = make_list(make_string(identifier), list); + elem->info.node.head = list; + elem->lineno = yylineno; + + return elem; +} + ast *make_constant(char *identifier, long num) { ast *elem = safe_malloc(sizeof(ast)); @@ -297,13 +312,13 @@ ast *make_case_statement_number(long num return elem; } -ast *make_return_statement(void) +ast *make_return_statement(ast *expression) { ast *elem = safe_malloc(sizeof(ast)); elem->tag = node_ast; elem->info.node.tag = stmt_return; - elem->info.node.head = NULL; + elem->info.node.head = make_list(expression, NULL); elem->lineno = yylineno; return elem; ============================================================ --- src/lsc/ast.h 3c28d1b6a01e8e99c8f9485c9771e5f9df66ec83 +++ src/lsc/ast.h c16257876c942379840ba94428e4bbbc807d8216 @@ -5,6 +5,7 @@ ast *make_fndefint(char *, long); ast *make_list_node(ast_list *); ast *make_function(char *, ast_list *, ast_list *); ast *make_fndefint(char *, long); +ast *make_fndefint_v(char *, long); ast *make_constant(char *, long); ast *make_realconstant(char *, float); ast *make_fndefext(char *); @@ -22,6 +23,6 @@ ast *make_default_statement(); ast *make_case_statement_variable(char *); ast *make_break_statement(); ast *make_default_statement(); -ast *make_return_statement(); +ast *make_return_statement(ast *); void ast_dump(ast *); ============================================================ --- src/lsc/codegen.c 3f17dcc09e552288f4a68b0ac58692cffd524364 +++ src/lsc/codegen.c 59287d90158eaceceb9a87f9fe6f6c45059c6cb6 @@ -95,10 +95,14 @@ struct instr *instr_tail = NULL; #define VAR_ARG 1 #define VAR_REAL 2 +#define FN_TYPE_BASE 0xff + #define FN_INT 1 #define FN_STR 2 #define FN_LOCAL 3 +#define FN_VARARGS 0x100 + int fnconst; int nargs; int local_variable_count = -1; @@ -146,7 +150,7 @@ void output_functions_action(struct hash { int len, pad; - if (ptr->flags == FN_LOCAL) { + if ((ptr->flags & FN_TYPE_BASE) == FN_LOCAL) { len = strlen(ptr->name) + 1 + 16; pad = (4 - (len % 4)) % 4; output_int(len+pad); @@ -311,7 +315,7 @@ void create_function(char *fnname, int t compiler_error("Function already exists"); if (output_asm) { - switch (type) { + switch (type & FN_TYPE_BASE) { case FN_INT: printf("%%fnint %s %d\n", fnname, num); break; @@ -644,12 +648,14 @@ void codegen(ast *node) case node_ast: switch (node->info.node.tag) { case kind_fndefint: + case kind_fndefint_v: assert(sp == 0); assert(node->info.node.head != NULL); assert(node->info.node.head->next != NULL); create_function(node->info.node.head->elem->info.string, - FN_INT, + FN_INT | ((node->info.node.tag == + kind_fndefint_v) ? FN_VARARGS : 0), node->info.node.head->next->elem->info.integer); break; case kind_constant: @@ -771,20 +777,36 @@ void codegen(ast *node) // printf("savedsp = %d\n", savedsp); + nargs = 0; + /* Evaluate the arguments first */ for (ptr = node->info.node.head->next->elem->info.node.head; ptr; ptr = ptr->next) { codegen(ptr->elem); + nargs++; } // printf("sp = %d\n", sp); + if (!lookup_function(node->info.node.head->elem, &fn)) + compiler_error("Function not found"); + + if (fn.type & FN_VARARGS) { + /* + * The last argument is the number of + * arguments to expect in the case + * of variable argument length. + * This is something only supported for + * builtin functions at present. + */ + emit_instr_immediate(OP_PUSH, nargs); + sp++; + } + emit_instr_immediate(OP_ALLOC, 1); sp++; - if (!lookup_function(node->info.node.head->elem, &fn)) - compiler_error("Function not found"); switch (fn.type) { case FN_INT: emit_instr_immediate(OP_CALLNUM, fn.num); @@ -1147,8 +1169,12 @@ void codegen(ast *node) emit_instr_label(OP_B, breaklabel); break; case stmt_return: - assert(node->info.node.head == NULL); - + if (node->info.node.head) { + /* Return value */ + codegen(node->info.node.head->elem); + emit_instr_imm_const(OP_STORE, sp, fnconst); + sp--; + } emit_instr_imm_const(OP_POP, sp, fnconst); emit_simple_instr(OP_RET); break; ============================================================ --- src/lsc/lexer.l 88be4de3325822fc6a95e81cc8c615a6c70078bf +++ src/lsc/lexer.l abb8ad18ba69e18853d003ba9da3ab968f58d165 @@ -86,6 +86,7 @@ fndefint return TOKFNDEFINT; function return TOKFUNCTION; fndefint return TOKFNDEFINT; +fndefint_v return TOKFNDEFINT_V; fndefext return TOKFNDEFEXT; constant return TOKCONSTANT; while return TOKWHILE; ============================================================ --- src/lsc/parser.y a3d3372576329c2dc4221d54c0a05238eb86dece +++ src/lsc/parser.y 2e92a218e99f7522cbd4a48694ec2202d575e0d2 @@ -68,7 +68,7 @@ int main(int argc, char *argv[]) %} -%token TOKFUNCTION TOKFNDEFINT TOKFNDEFEXT TOKCONSTANT +%token TOKFUNCTION TOKFNDEFINT TOKFNDEFINT_V TOKFNDEFEXT TOKCONSTANT %token TOKWHILE TOKIF TOKELSE TOKSWITCH TOKCASE TOKDEFAULT %token TOKBREAK TOKRETURN TOKEQ TOKNE TOKAND TOKOR STRING @@ -86,6 +86,7 @@ int main(int argc, char *argv[]) %type <Tast> fndefint %type <Tast> fndefext %type <Tast> statement +%type <Tast> fndefint_v %type <Tast> assignment %type <Tast> expression %type <Tast> realconstant @@ -142,6 +143,7 @@ fn_list_inner: fn_list_inner: fn_list_inner function { $$ = make_list($2, $1); } | fn_list_inner fndefint { $$ = make_list($2, $1); } + | fn_list_inner fndefint_v { $$ = make_list($2, $1); } | fn_list_inner fndefext { $$ = make_list($2, $1); } | fn_list_inner constant { $$ = make_list($2, $1); } | fn_list_inner realconstant { $$ = make_list($2, $1); } @@ -158,6 +160,11 @@ fndefint: { $$ = make_fndefint($2, $3); } ; +fndefint_v: + TOKFNDEFINT_V IDENTIFIER NUMBER ';' + { $$ = make_fndefint_v($2, $3); } + ; + constant: TOKCONSTANT IDENTIFIER NUMBER ';' { $$ = make_constant($2, $3); } @@ -319,8 +326,11 @@ statement_return: ; statement_return: + TOKRETURN expression + { $$ = make_return_statement($2); } + | TOKRETURN - { $$ = make_return_statement(); } + { $$ = make_return_statement(NULL); } ; statement_break: ============================================================ --- src/lsc/types.h 0934f3373a49335fb48fc8fb0d9be2350c843533 +++ src/lsc/types.h b169b733d6297c1e15359d339d187ae7e5798f9b @@ -2,8 +2,8 @@ typedef enum { typedef enum { - kind_fndef, kind_fndefint, kind_fndefext, kind_constant, - kind_assign, kind_list, kind_call, kind_array, + kind_fndef, kind_fndefint, kind_fndefint_v, kind_fndefext, + kind_constant, kind_assign, kind_list, kind_call, kind_array, op_plus, op_minus, op_times, op_divide, op_gt, op_lt, op_ge, op_le, op_eq, op_ne, ============================================================ --- src/lsi/Makefile 609a07c3b2f5a6dcc33cb70112821fa46ab8ade0 +++ src/lsi/Makefile 78a1f906a0569af4ace0697000ac5411211fcc1c @@ -3,9 +3,9 @@ OBJS= main.o vm.o plugins.o dmx.o midi.o PREFIX?= /usr/local OBJS= main.o vm.o plugins.o dmx.o midi.o beatdetect.o fft.o map3d.o mouse.o \ - cmdsocket.o + cmdsocket.o sql.o SRCS= main.c vm.c plugins.c dmx.c midi.c beatdetect.c fft.c map3d.c mouse.c \ - cmdsocket.c + cmdsocket.c sql.c OBJS+= abi.o SRCS+= abi.c @@ -14,10 +14,13 @@ INCDIR= ../include COMMONDIR= ../common INCDIR= ../include +SQLITEINCDIR= /usr/pkg/include +SQLITELIBDIR= /usr/pkg/lib CFLAGS+= -Wall -Werror -CPPFLAGS+= -I${INCDIR} -LDLIBS+= -lm +CPPFLAGS+= -I${INCDIR} -I${SQLITEINCDIR} +LDFLAGS+= -L${SQLITELIBDIR} -Wl,-R${SQLITELIBDIR} +LDLIBS+= -lm -lsqlite3 PROGOBJS= ${OBJS} ${COMMONOBJS:S/^/${COMMONDIR}\//} ============================================================ --- src/lsi/abi.h f5ff3bd7144f8020da012ea0158aa51d862f888e +++ src/lsi/abi.h 0553ade9748fed1e6808e874fa67020a6dd52a22 @@ -49,3 +49,5 @@ int vm_intfn_cmdsocket_prefix(void); int vm_intfn_cmdsocket_read(void); int vm_intfn_cmdsocket_write(void); int vm_intfn_cmdsocket_prefix(void); +int vm_intfn_sql_query(void); +int vm_intfn_sql_query_1s(void); ============================================================ --- src/lsi/abispec e8cad560a662c1abc9da835eedd7dddafa77d03f +++ src/lsi/abispec 14bb48cc77b6f36777d424e8a354f629082b14e8 @@ -38,6 +38,9 @@ function cmdsocket_prefix function cmdsocket_read function cmdsocket_write function cmdsocket_prefix +/* NOT_YET function_v sql_query */ +function sql_query +function sql_query_1s /* * The ABI should be identified by a SHA1 hash of this file ============================================================ --- src/lsi/makeabi af04da9852be189b121ae5a7e48a4664afc10c7d +++ src/lsi/makeabi 54d8bf7ee907e67849843b113a8c6f5039ec020b @@ -37,6 +37,13 @@ do_function() FNCOUNT=$((${FNCOUNT}+1)) } +do_function_v() +{ + echo " vm_intfn_${ARG1}," >>${ABI} + echo "fndefint_v ${ARG1} ${FNCOUNT};" >>${HEADER} + FNCOUNT=$((${FNCOUNT}+1)) +} + cat <<EOF >${ABI} /* abi.c */ /* autogenerated - do not edit */ @@ -69,6 +76,8 @@ do case "$TYPE" in function) do_function ;; + function_v) do_function_v + ;; esac done <${INFILE} ============================================================ --- src/lsi/mouse.c 410738f63d15db286b591fff6040fcdfe9e1cfa6 +++ src/lsi/mouse.c 51f025fd4be11edf4936c00a3316e4d1ee31b9a5 @@ -10,7 +10,7 @@ #include <stdio.h> #include "vm.h" -#define MOUSEDEVICE "/dev/wsmouse" +#define MOUSEDEVICE "/dev/wsmouse1" char *events[] = { "undefined", ============================================================ --- src/lsi/plugins.c d1249e7348b4b02e2405e3374b7e6609ff982875 +++ src/lsi/plugins.c f3e7cb50a5258da029d27c67f148fba7845fc552 @@ -12,6 +12,7 @@ #include "beatdetect.h" #include "mouse.h" #include "cmdsocket.h" +#include "sql.h" struct plugin plugins_table[] = { {"midi", midi_init, midi_close, 0}, @@ -19,6 +20,7 @@ struct plugin plugins_table[] = { {"beatdetect", beatdetect_init, beatdetect_close, 0}, {"mouse", mouse_init, mouse_close, 0}, {"cmdsocket", cmdsocket_init, cmdsocket_close, 0}, + {"sql", sql_init, sql_close, 0}, }; int nplugins = (sizeof(plugins_table) / sizeof(struct plugin)); ============================================================ --- src/lsi/vm.c 0d1a3539301653c5f5cad4792072a3f87ee17d29 +++ src/lsi/vm.c c29bc86ce0d4170f8a0229735384ea9eea76763f @@ -23,6 +23,7 @@ #include "map3d.h" #include "mouse.h" #include "cmdsocket.h" +#include "sql.h" #define DEBUG 0 @@ -482,6 +483,121 @@ int vm_intfn_cmdsocket_write(void) return 1; } +#ifdef NOT_YET + +#define MIN(a, b) ((a < b) ? a : b) + +#define MORE_QUERY_N(x, n) do { \ + off = strncpy(buf+off, (x), MIN(VM_STRING_MAX-off, (n)) - buf;\ + if (off >= VM_STRING_MAX) { \ + printf("Excessive string length - can't perform query\n"); \ + return 1; \ + } \ + } while (0) + +#define MORE_QUERY(x) MORE_QUERY_N((x), VM_STRING_MAX) + +int vm_intfn_sql_query(void) +{ + int nargs = stack_get(vm_current, 1); + int len = stack_get(vm_current, nargs+1); + char *fmt = stack_getstr(vm_current, len, nargs+1); + char buf1[VM_STRING_MAX]; + char buf2[VM_STRING_MAX]; + char buf[VM_STRING_MAX]; + int off = 0; + int result; + int next; + char *p, *p1; + + if (len > VM_STRING_MAX) { + printf("Excessive string length - can't perform query\n"); + return 1; + } + strncpy(buf1, fmt, len); + buf1[len] = '\0'; + + p = buf1; + while (p1 = strchr(p, '%') { + if (p1) { + *p1 = 0; + } + if (p != buf1) { + switch(*p) { + case '%': + MORE_QUERY("%"); + break; + case 's': + next = (len + sizeof(stkentry)-1) / sizeof(stkentry) + 1; + + MORE_QUERY_N(stack_getstr(vm_current, slen, nargs)); + } + } + MORE_QUERY(p); + if (p1) + p = p1; + else + break; + } + + sql_query(buffer, len, &result); + /* XXX what to do with an error here? */ + stack_poke(vm_current, 0, result); /* return value */ + return 1; +} +#else +int vm_intfn_sql_query(void) +{ + int len = stack_get(vm_current, 1); + char *query = stack_getstr(vm_current, len, 1); + int result; + + sql_query(query, len, &result); + /* XXX what to do with an error here? */ + stack_poke(vm_current, 0, result); /* return value */ + return 1; +} + +int vm_intfn_sql_query_1s(void) +{ + int len1, len2; + char buf1[VM_STRING_MAX]; + char buf2[VM_STRING_MAX]; + char query[VM_STRING_MAX]; + char *arg1; + char *arg2; + int result; + int next; + + next = 1; + + len2 = stack_get(vm_current, next); + arg2 = stack_getstr(vm_current, len2, next); + + next += (len2 + sizeof(stkentry)-1) / sizeof(stkentry) + 1; + + len1 = stack_get(vm_current, next); + arg1 = stack_getstr(vm_current, len1, next); + + if ((len1 > VM_STRING_MAX) || (len2 > VM_STRING_MAX)) { + printf("Excessive string length - can't perform query\n"); + return 1; + } + strncpy(buf1, arg1, len1); + buf1[len1] = '\0'; + strncpy(buf2, arg2, len2); + buf2[len2] = '\0'; + + snprintf(query, VM_STRING_MAX, buf1, buf2); + + sql_query(query, strlen(query), &result); + + /* XXX what to do with an error here? */ + stack_poke(vm_current, 0, result); /* return value */ + return 1; +} +#endif + int vm_intfn_beatdetect_read(void) { if (!beatdetect_read()) {