Browse Source

Sol Part 6: Now with More Pylons!

master
Grissess 7 years ago
parent
commit
4ea5565623
  1. 2
      .gitignore
  2. 0
      build.sh
  3. 13
      builtins.c
  4. 50
      cdata.h
  5. 71
      lex.yy.c
  6. 7
      object.c
  7. 24
      parser.output
  8. 1652
      parser.tab.c
  9. 153
      parser.tab.h
  10. 19
      runtime.c
  11. 2
      sol.h
  12. 25
      solrun.c
  13. 60
      state.c
  14. 56
      test.sol

2
.gitignore

@ -0,0 +1,2 @@
sol
*.o

0
testbuild.sh → build.sh

13
builtins.c

@ -61,7 +61,9 @@ sol_object_t *sol_f_tostring(sol_state_t *state, sol_object_t *args) {
sol_object_t *sol_f_try(sol_state_t *state, sol_object_t *args) {
sol_object_t *func = sol_list_get_index(state, args, 0), *fargs = sol_list_sublist(state, args, 1);
sol_object_t *ls = sol_new_list(state), *one = sol_new_int(state, 1);
sol_object_t *res = func->ops->call(state, fargs);
sol_object_t *res;
sol_list_insert(state, fargs, 0, func);
res = func->ops->call(state, fargs);
sol_obj_free(func);
sol_obj_free(fargs);
if(sol_has_error(state)) {
@ -123,7 +125,7 @@ void ob_print(sol_object_t *obj) {
case SOL_STRING:
printf("\"%s\"", obj->str);
break;
case SOL_LCELL:
printf("<<");
/* fall through */
@ -142,7 +144,7 @@ void ob_print(sol_object_t *obj) {
}
printf("]");
break;
case SOL_MCELL:
printf("<<");
/* fall through */
@ -330,15 +332,16 @@ sol_object_t *sol_f_iter_map(sol_state_t *state, sol_object_t *args) {
index = obj;
sol_map_set_name(state, local, "idx", index);
}
while(index && !index->mkey) index = index->mnext;
if(!index || !index->mnext) {
if(!index || index == state->StopIteration) {
sol_obj_free(index);
sol_obj_free(obj);
sol_obj_free(local);
return sol_incref(state->StopIteration);
}
while(index && !index->mkey) index = index->mnext;
res = sol_incref(index->mkey);
index = index->mnext;
if(!index) index = state->StopIteration;
sol_map_set_name(state, local, "idx", index);
sol_obj_free(index);
sol_obj_free(local);

50
cdata.h

@ -0,0 +1,50 @@
#ifndef CDATA_H
#define CDATA_H
#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_memtype_t
typedef struct {
sol_memtype_t type;
union {
int offset;
sol_cfunc_t cfunc;
};
} sol_memspec_t;
typedef struct {
void *data;
sol_object_t *specs;
} sol_cstruct_t;
sol_object_t *sol_new_cstruct_specs(sol_state_t *);
void sol_cstruct_add_member(sol_state_t *, sol_object_t *, sol_object_t *, sol_memspec_t, int);
void sol_cstruct_add_member_name(sol_state_t *, sol_object_t *, char *, sol_memspec_t, int);
void sol_cstruct_add_func(sol_state_t *, sol_object_t *, sol_object_t *, sol_cfunc_t);
void sol_cstruct_add_func_name(sol_state_t *, sol_object_t *, char *, sol_cfunc_t);
sol_object_t *sol_new_cstruct(sol_state_t *, void *, sol_object_t *);
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 *)
#endif

71
lex.yy.c

@ -8,7 +8,7 @@
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
#define YY_FLEX_SUBMINOR_VERSION 35
#define YY_FLEX_SUBMINOR_VERSION 39
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
@ -161,7 +161,12 @@ typedef unsigned int flex_uint32_t;
typedef struct yy_buffer_state *YY_BUFFER_STATE;
#endif
extern int yyleng;
#ifndef YY_TYPEDEF_YY_SIZE_T
#define YY_TYPEDEF_YY_SIZE_T
typedef size_t yy_size_t;
#endif
extern yy_size_t yyleng;
extern FILE *yyin, *yyout;
@ -170,6 +175,7 @@ extern FILE *yyin, *yyout;
#define EOB_ACT_LAST_MATCH 2
#define YY_LESS_LINENO(n)
#define YY_LINENO_REWIND_TO(ptr)
/* Return all but the first "n" matched characters back to the input stream. */
#define yyless(n) \
@ -187,11 +193,6 @@ extern FILE *yyin, *yyout;
#define unput(c) yyunput( c, (yytext_ptr) )
#ifndef YY_TYPEDEF_YY_SIZE_T
#define YY_TYPEDEF_YY_SIZE_T
typedef size_t yy_size_t;
#endif
#ifndef YY_STRUCT_YY_BUFFER_STATE
#define YY_STRUCT_YY_BUFFER_STATE
struct yy_buffer_state
@ -209,7 +210,7 @@ struct yy_buffer_state
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
*/
int yy_n_chars;
yy_size_t yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to
@ -279,8 +280,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
/* yy_hold_char holds the character lost when yytext is formed. */
static char yy_hold_char;
static int yy_n_chars; /* number of characters read into yy_ch_buf */
int yyleng;
static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */
yy_size_t yyleng;
/* Points to current character in buffer. */
static char *yy_c_buf_p = (char *) 0;
@ -308,7 +309,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len );
YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len );
void *yyalloc (yy_size_t );
void *yyrealloc (void *,yy_size_t );
@ -577,7 +578,7 @@ void str_putc(char c) {
<STRING>. { str_putc(*yytext); }
*/
#line 581 "lex.yy.c"
#line 582 "lex.yy.c"
#define INITIAL 0
@ -616,7 +617,7 @@ FILE *yyget_out (void );
void yyset_out (FILE * out_str );
int yyget_leng (void );
yy_size_t yyget_leng (void );
char *yyget_text (void );
@ -764,11 +765,6 @@ YY_DECL
register char *yy_cp, *yy_bp;
register int yy_act;
#line 57 "tokenizer.lex"
#line 771 "lex.yy.c"
if ( !(yy_init) )
{
(yy_init) = 1;
@ -795,6 +791,12 @@ YY_DECL
yy_load_buffer_state( );
}
{
#line 57 "tokenizer.lex"
#line 799 "lex.yy.c"
while ( 1 ) /* loops until end-of-file is reached */
{
yy_cp = (yy_c_buf_p);
@ -811,7 +813,7 @@ YY_DECL
yy_match:
do
{
register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
if ( yy_accept[yy_current_state] )
{
(yy_last_accepting_state) = yy_current_state;
@ -1154,7 +1156,7 @@ YY_RULE_SETUP
#line 177 "tokenizer.lex"
ECHO;
YY_BREAK
#line 1158 "lex.yy.c"
#line 1160 "lex.yy.c"
case YY_STATE_EOF(INITIAL):
yyterminate();
@ -1285,6 +1287,7 @@ case YY_STATE_EOF(INITIAL):
"fatal flex scanner internal error--no action found" );
} /* end of action switch */
} /* end of scanning one token */
} /* end of user's declarations */
} /* end of yylex */
/* yy_get_next_buffer - try to read in a new buffer
@ -1340,21 +1343,21 @@ static int yy_get_next_buffer (void)
else
{
int num_to_read =
yy_size_t num_to_read =
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
while ( num_to_read <= 0 )
{ /* Not enough room in the buffer - grow it. */
/* just a shorter name for the current buffer */
YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
int yy_c_buf_p_offset =
(int) ((yy_c_buf_p) - b->yy_ch_buf);
if ( b->yy_is_our_buffer )
{
int new_size = b->yy_buf_size * 2;
yy_size_t new_size = b->yy_buf_size * 2;
if ( new_size <= 0 )
b->yy_buf_size += b->yy_buf_size / 8;
@ -1385,7 +1388,7 @@ static int yy_get_next_buffer (void)
/* Read in more data. */
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
(yy_n_chars), (size_t) num_to_read );
(yy_n_chars), num_to_read );
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
}
@ -1480,7 +1483,7 @@ static int yy_get_next_buffer (void)
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
yy_is_jam = (yy_current_state == 110);
return yy_is_jam ? 0 : yy_current_state;
return yy_is_jam ? 0 : yy_current_state;
}
static void yyunput (int c, register char * yy_bp )
@ -1495,7 +1498,7 @@ static int yy_get_next_buffer (void)
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
{ /* need to shift things up to make room */
/* +2 for EOB chars. */
register int number_to_move = (yy_n_chars) + 2;
register yy_size_t number_to_move = (yy_n_chars) + 2;
register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
register char *source =
@ -1544,7 +1547,7 @@ static int yy_get_next_buffer (void)
else
{ /* need more input */
int offset = (yy_c_buf_p) - (yytext_ptr);
yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
++(yy_c_buf_p);
switch ( yy_get_next_buffer( ) )
@ -1704,10 +1707,6 @@ static void yy_load_buffer_state (void)
yyfree((void *) b );
}
#ifndef __cplusplus
extern int isatty (int );
#endif /* __cplusplus */
/* Initializes or reinitializes a buffer.
* This function is sometimes called more than once on the same buffer,
* such as during a yyrestart() or at EOF.
@ -1820,7 +1819,7 @@ void yypop_buffer_state (void)
*/
static void yyensure_buffer_stack (void)
{
int num_to_alloc;
yy_size_t num_to_alloc;
if (!(yy_buffer_stack)) {
@ -1917,12 +1916,12 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
*
* @return the newly allocated buffer state object.
*/
YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len )
{
YY_BUFFER_STATE b;
char *buf;
yy_size_t n;
int i;
yy_size_t i;
/* Get memory for full buffer, including space for trailing EOB's. */
n = _yybytes_len + 2;
@ -2004,7 +2003,7 @@ FILE *yyget_out (void)
/** Get the length of the current token.
*
*/
int yyget_leng (void)
yy_size_t yyget_leng (void)
{
return yyleng;
}
@ -2152,7 +2151,7 @@ void yyfree (void * ptr )
#define YYTABLES_NAME "yytables"
#line 177 "tokenizer.lex"
#line 176 "tokenizer.lex"

7
object.c

@ -229,10 +229,11 @@ void sol_list_set_index(sol_state_t *state, sol_object_t *list, int idx, sol_obj
if(cur->lvalue) i++;
cur = cur->lnext;
}
while(!cur->lvalue) cur = cur->lnext;
if(cur) {
temp = cur->lvalue;
cur->lvalue = sol_incref(obj);
sol_obj_free(temp);
if(temp) sol_obj_free(temp);
} else {
sol_obj_free(sol_set_error_string(state, "Set out-of-bounds index"));
return;
@ -490,6 +491,7 @@ void sol_map_set(sol_state_t *state, sol_object_t *map, sol_object_t *key, sol_o
cur->mval = NULL;
}
} else {
sol_obj_free(cur->mval);
cur->mval = sol_incref(val);
}
return;
@ -522,7 +524,7 @@ void sol_map_set_existing(sol_state_t *state, sol_object_t *map, sol_object_t *k
if(cur->mkey) {
sol_list_insert(state, list, 1, cur->mkey);
cmp = sol_cast_int(state, key->ops->cmp(state, list));
sol_obj_free(sol_list_remove(state, list, 1));
sol_list_remove(state, list, 1);
if(cmp->ival == 0) {
if(sol_is_none(state, val)) {
if(prev) {
@ -535,6 +537,7 @@ void sol_map_set_existing(sol_state_t *state, sol_object_t *map, sol_object_t *k
cur->mval = NULL;
}
} else {
sol_obj_free(cur->mval);
cur->mval = sol_incref(val);
}
return;

24
parser.output

@ -145,7 +145,7 @@ Grammar
68 | index_expr
69 opt_stmt: stmt
70 | /* empty */
70 | %empty
71 index_expr: expr LBRACKET expr RBRACKET
72 | expr DOT IDENT
@ -170,17 +170,17 @@ Grammar
87 paren_expr: LPAREN expr RPAREN
88 expr_list: /* empty */
88 expr_list: %empty
89 | expr
90 | expr_list expr
91 | expr_list COMMA expr
92 ident_list: /* empty */
92 ident_list: %empty
93 | IDENT
94 | ident_list IDENT
95 | ident_list COMMA IDENT
96 assoc_list: /* empty */
96 assoc_list: %empty
97 | assoc_item
98 | assoc_list assoc_item
99 | assoc_list COMMA assoc_item
@ -1100,7 +1100,7 @@ State 15
State 16
85 gen_expr: LBRACE . assoc_list RBRACE
96 assoc_list: . [IDENT, RBRACE, LBRACKET, COMMA]
96 assoc_list: . %empty [IDENT, RBRACE, LBRACKET, COMMA]
97 | . assoc_item
98 | . assoc_list assoc_item
99 | . assoc_list COMMA assoc_item
@ -1301,7 +1301,7 @@ State 18
85 | . LBRACE assoc_list RBRACE
86 | . paren_expr
87 paren_expr: . LPAREN expr RPAREN
88 expr_list: . [FUNC, NONE, IDENT, INT, FLOAT, STRING, MINUS, BNOT, LNOT, LBRACE, LPAREN, LBRACKET, RBRACKET, COMMA, POUND]
88 expr_list: . %empty [FUNC, NONE, IDENT, INT, FLOAT, STRING, MINUS, BNOT, LNOT, LBRACE, LPAREN, LBRACKET, RBRACKET, COMMA, POUND]
89 | . expr
90 | . expr_list expr
91 | . expr_list COMMA expr
@ -2000,7 +2000,7 @@ State 44
State 45
67 funcdecl_expr: FUNC LPAREN . ident_list RPAREN opt_stmt END
92 ident_list: . [IDENT, RPAREN, COMMA]
92 ident_list: . %empty [IDENT, RPAREN, COMMA]
93 | . IDENT
94 | . ident_list IDENT
95 | . ident_list COMMA IDENT
@ -5784,7 +5784,7 @@ State 91
85 | . LBRACE assoc_list RBRACE
86 | . paren_expr
87 paren_expr: . LPAREN expr RPAREN
88 expr_list: . [FUNC, NONE, IDENT, INT, FLOAT, STRING, MINUS, BNOT, LNOT, LBRACE, LPAREN, RPAREN, LBRACKET, COMMA, POUND]
88 expr_list: . %empty [FUNC, NONE, IDENT, INT, FLOAT, STRING, MINUS, BNOT, LNOT, LBRACE, LPAREN, RPAREN, LBRACKET, COMMA, POUND]
89 | . expr
90 | . expr_list expr
91 | . expr_list COMMA expr
@ -7200,7 +7200,7 @@ State 104
State 105
66 funcdecl_expr: FUNC IDENT LPAREN . ident_list RPAREN opt_stmt END
92 ident_list: . [IDENT, RPAREN, COMMA]
92 ident_list: . %empty [IDENT, RPAREN, COMMA]
93 | . IDENT
94 | . ident_list IDENT
95 | . ident_list COMMA IDENT
@ -8964,7 +8964,7 @@ State 161
67 | FUNC LPAREN ident_list RPAREN . opt_stmt END
68 | . index_expr
69 opt_stmt: . stmt
70 | . [END]
70 | . %empty [END]
71 index_expr: . expr LBRACKET expr RBRACKET
72 | . expr DOT IDENT
73 | . ref_expr
@ -9177,7 +9177,7 @@ State 169
85 | . LBRACE assoc_list RBRACE
86 | . paren_expr
87 paren_expr: . LPAREN expr RPAREN
88 expr_list: . [FUNC, NONE, IDENT, INT, FLOAT, STRING, MINUS, BNOT, LNOT, LBRACE, LPAREN, RPAREN, LBRACKET, COMMA, POUND]
88 expr_list: . %empty [FUNC, NONE, IDENT, INT, FLOAT, STRING, MINUS, BNOT, LNOT, LBRACE, LPAREN, RPAREN, LBRACKET, COMMA, POUND]
89 | . expr
90 | . expr_list expr
91 | . expr_list COMMA expr
@ -9577,7 +9577,7 @@ State 174
67 | . FUNC LPAREN ident_list RPAREN opt_stmt END
68 | . index_expr
69 opt_stmt: . stmt
70 | . [END]
70 | . %empty [END]
71 index_expr: . expr LBRACKET expr RBRACKET
72 | . expr DOT IDENT
73 | . ref_expr

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

153
parser.tab.h

@ -1,19 +1,19 @@
/* A Bison parser, made by GNU Bison 2.7.12-4996. */
/* A Bison parser, made by GNU Bison 3.0.2. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
@ -26,13 +26,13 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
#ifndef YY_YY_PARSER_TAB_H_INCLUDED
# define YY_YY_PARSER_TAB_H_INCLUDED
/* Enabling traces. */
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 1
#endif
@ -40,93 +40,80 @@
extern int yydebug;
#endif
/* Tokens. */
/* Token type. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
IF = 258,
THEN = 259,
ELSE = 260,
WHILE = 261,
FOR = 262,
IN = 263,
DO = 264,
FUNC = 265,
RETURN = 266,
BREAK = 267,
CONTINUE = 268,
END = 269,
NONE = 270,
IDENT = 271,
INT = 272,
FLOAT = 273,
STRING = 274,
PLUS = 275,
MINUS = 276,
STAR = 277,
SLASH = 278,
DSTAR = 279,
BAND = 280,
BOR = 281,
BXOR = 282,
BNOT = 283,
LAND = 284,
LOR = 285,
LNOT = 286,
ASSIGN = 287,
ASSIGNPLUS = 288,
ASSIGNMINUS = 289,
ASSIGNSTAR = 290,
ASSIGNSLASH = 291,
ASSIGNDSTAR = 292,
ASSIGNBAND = 293,
ASSIGNBOR = 294,
ASSIGNBXOR = 295,
EQUAL = 296,
LESS = 297,
GREATER = 298,
LESSEQ = 299,
GREATEREQ = 300,
RSHIFT = 301,
LSHIFT = 302,
LBRACE = 303,
RBRACE = 304,
LPAREN = 305,
RPAREN = 306,
LBRACKET = 307,
RBRACKET = 308,
DOT = 309,
COLON = 310,
SEMICOLON = 311,
COMMA = 312,
POUND = 313
};
enum yytokentype
{
IF = 258,
THEN = 259,
ELSE = 260,
WHILE = 261,
FOR = 262,
IN = 263,
DO = 264,
FUNC = 265,
RETURN = 266,
BREAK = 267,
CONTINUE = 268,
END = 269,
NONE = 270,
IDENT = 271,
INT = 272,
FLOAT = 273,
STRING = 274,
PLUS = 275,
MINUS = 276,
STAR = 277,
SLASH = 278,
DSTAR = 279,
BAND = 280,
BOR = 281,
BXOR = 282,
BNOT = 283,
LAND = 284,
LOR = 285,
LNOT = 286,
ASSIGN = 287,
ASSIGNPLUS = 288,
ASSIGNMINUS = 289,
ASSIGNSTAR = 290,
ASSIGNSLASH = 291,
ASSIGNDSTAR = 292,
ASSIGNBAND = 293,
ASSIGNBOR = 294,
ASSIGNBXOR = 295,
EQUAL = 296,
LESS = 297,
GREATER = 298,
LESSEQ = 299,
GREATEREQ = 300,
RSHIFT = 301,
LSHIFT = 302,
LBRACE = 303,
RBRACE = 304,
LPAREN = 305,
RPAREN = 306,
LBRACKET = 307,
RBRACKET = 308,
DOT = 309,
COLON = 310,
SEMICOLON = 311,
COMMA = 312,
POUND = 313
};
#endif
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE yylval;
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
int yyparse (void *YYPARSE_PARAM);
#else
int yyparse ();
#endif
#else /* ! YYPARSE_PARAM */
#if defined __STDC__ || defined __cplusplus
int yyparse (stmt_node **program);
#else
int yyparse ();
#endif
#endif /* ! YYPARSE_PARAM */
#endif /* !YY_YY_PARSER_TAB_H_INCLUDED */

19
runtime.c

@ -179,7 +179,7 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
case LIT_STRING:
return sol_new_string(state, expr->lit->str);
break;
case LIT_NONE:
return sol_incref(state->None);
break;
@ -280,11 +280,11 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
case OP_GREATEREQ:
res = sol_new_int(state, BOOL_TO_INT(sol_cast_int(state, left->ops->cmp(state, list))->ival>=0));
break;
case OP_LSHIFT:
res = left->ops->blsh(state, list);
break;
case OP_RSHIFT:
res = left->ops->brsh(state, list);
break;
@ -316,7 +316,7 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
res = sol_new_int(state, BOOL_TO_INT(!lint->ival));
sol_obj_free(lint);
break;
case OP_LEN:
res = left->ops->len(state, list);
break;
@ -492,9 +492,16 @@ sol_object_t *sol_f_func_call(sol_state_t *state, sol_object_t *args) {
sol_object_t *res, *scope, *value, *curo = args, *key;
identlist_node *curi;
while(curo && !curo->lvalue) curo = curo->lnext;
if(!curo) return sol_incref(state->None);
if(!curo) {
printf("WARNING: No parameters to function call (expecting function)\n");
return sol_incref(state->None);
}
value = curo->lvalue;
if(!value || !value->func) return sol_incref(state->None);
if(!value || !sol_is_func(value)) {
printf("WARNING: Function call without function as first parameter\n");
return sol_incref(state->None);
}
if(!value->func) return sol_incref(state->None);
curo = curo->lnext;
while(curo && !curo->lvalue) curo = curo->lnext;
scope = sol_map_copy(state, value->closure);

2
sol.h

@ -128,6 +128,8 @@ sol_object_t *sol_set_error(sol_state_t *, sol_object_t *);
sol_object_t *sol_set_error_string(sol_state_t *, const char *);
void sol_clear_error(sol_state_t *);
void sol_ops_init(sol_ops_t *);
// builtins.c
sol_object_t *sol_f_not_impl(sol_state_t *, sol_object_t *);

25
solrun.c

@ -5,12 +5,28 @@
int main(int argc, char **argv) {
stmt_node *program;
sol_state_t state;
if(argc > 1) yydebug = 1;
char *c;
int printtree = 0;
if(argc>1) {
c = argv[1];
while(*c) {
switch(*c) {
case 'd':
yydebug = 1;
break;
case 't':
printtree = 1;
break;
}
c++;
}
}
program = sol_compile_file(stdin);
st_print(program);
if(printtree) st_print(program);
if(program) {
sol_state_init(&state);
@ -20,8 +36,11 @@ int main(int argc, char **argv) {
ob_print(state.error);
printf("\n");
}
//st_free(program);
return 0;
}
printf("NULL program (probably a syntax error)");
return 1;
}

60
state.c

@ -20,28 +20,8 @@ int sol_state_init(sol_state_t *state) {
//Initialize all of the builtin operations
//(these ones are technically already pointed to by None/OOM)
state->NullOps.add = sol_f_not_impl;
state->NullOps.sub = sol_f_not_impl;
state->NullOps.mul = sol_f_not_impl;
state->NullOps.div = sol_f_not_impl;
state->NullOps.band = sol_f_not_impl;
state->NullOps.bor = sol_f_not_impl;
state->NullOps.bxor = sol_f_not_impl;
state->NullOps.blsh = sol_f_not_impl;
state->NullOps.brsh = sol_f_not_impl;
state->NullOps.bnot = sol_f_not_impl;
state->NullOps.cmp = sol_f_default_cmp;
state->NullOps.call = sol_f_not_impl;
state->NullOps.index = sol_f_not_impl;
state->NullOps.setindex = sol_f_not_impl;
state->NullOps.len = sol_f_not_impl;
state->NullOps.iter = sol_f_not_impl;
state->NullOps.toint = sol_f_not_impl;
state->NullOps.tofloat = sol_f_not_impl;
state->NullOps.tostring = sol_f_not_impl;
state->NullOps.init = sol_f_no_op;
state->NullOps.free = sol_f_no_op;
sol_ops_init(&(state->NullOps));
state->IntOps = state->NullOps;
state->FloatOps = state->NullOps;
state->StringOps = state->NullOps;
@ -95,7 +75,7 @@ int sol_state_init(sol_state_t *state) {
state->ListOps.iter = sol_f_list_iter;
state->ListOps.tostring = sol_f_list_tostring;
state->ListOps.free = sol_f_list_free;
state->LCellOps = state->ListOps;
state->LCellOps.free = sol_f_lcell_free;
@ -107,7 +87,7 @@ int sol_state_init(sol_state_t *state) {
state->MapOps.iter = sol_f_map_iter;
state->MapOps.tostring = sol_f_map_tostring;
state->MapOps.free = sol_f_map_free;
state->MCellOps = state->MapOps;
state->MCellOps.free = sol_f_mcell_free;
@ -141,7 +121,7 @@ int sol_state_init(sol_state_t *state) {
sol_map_set_name(state, globals, "rawget", sol_new_cfunc(state, sol_f_rawget));
sol_map_set_name(state, globals, "rawset", sol_new_cfunc(state, sol_f_rawset));
sol_map_set_name(state, globals, "range", sol_new_cfunc(state, sol_f_range));
sol_map_set_name(state, debug, "getref", sol_new_cfunc(state, sol_f_debug_getref));
sol_map_set_name(state, debug, "setref", sol_new_cfunc(state, sol_f_debug_setref));
sol_map_set_name(state, debug, "closure", sol_new_cfunc(state, sol_f_debug_closure));
@ -149,7 +129,7 @@ int sol_state_init(sol_state_t *state) {
sol_map_set_name(state, debug, "locals", sol_new_cfunc(state, sol_f_debug_locals));
sol_map_set_name(state, globals, "debug", debug);
sol_obj_free(debug);
sol_map_set_name(state, iter, "str", sol_new_cfunc(state, sol_f_iter_str));
sol_map_set_name(state, iter, "list", sol_new_cfunc(state, sol_f_iter_list));
sol_map_set_name(state, iter, "map", sol_new_cfunc(state, sol_f_iter_map));
@ -204,7 +184,7 @@ void sol_state_assign(sol_state_t *state, sol_object_t *key, sol_object_t *val)
if(cur->lvalue) active = cur;
next = cur->lnext;
}
if(!active) {
sol_set_error_string(state, "No scopes exist");
return;
@ -224,7 +204,7 @@ void sol_state_assign_name(sol_state_t *state, const char *name, sol_object_t *v
void sol_state_assign_l(sol_state_t *state, sol_object_t *key, sol_object_t *val) {
sol_object_t *cur = state->scopes;
while(cur && !cur->lvalue) cur = cur->lnext;
if(!cur) {
@ -278,3 +258,27 @@ void sol_clear_error(sol_state_t *state) {
state->error = sol_incref(state->None);
sol_obj_free(olderr);
}
void sol_ops_init(sol_ops_t *ops) {
ops->add = sol_f_not_impl;
ops->sub = sol_f_not_impl;
ops->mul = sol_f_not_impl;
ops->div = sol_f_not_impl;
ops->band = sol_f_not_impl;
ops->bor = sol_f_not_impl;
ops->bxor = sol_f_not_impl;
ops->blsh = sol_f_not_impl;
ops->brsh = sol_f_not_impl;
ops->bnot = sol_f_not_impl;
ops->cmp = sol_f_default_cmp;
ops->call = sol_f_not_impl;
ops->index = sol_f_not_impl;
ops->setindex = sol_f_not_impl;
ops->len = sol_f_not_impl;
ops->iter = sol_f_not_impl;
ops->toint = sol_f_not_impl;
ops->tofloat = sol_f_not_impl;
ops->tostring = sol_f_not_impl;
ops->init = sol_f_no_op;
ops->free = sol_f_no_op;
}

56
test.sol

@ -1,9 +1,12 @@
print('--- While loop')
a = 1
while a < 10 do
print(a)
a += 1
end
print("--- Range")
func mul9(b)
for i in range(#b) do
b[i] *= 9
@ -11,8 +14,18 @@ func mul9(b)
end
l = [1 2 3 4 5]
print(range(#l))
print("--- Iter list")
for i in l do print(i) end
print("--- Index list")
for i in range(#l) do print(i, l[i]) end
print('--- mul9')
mul9(l)
for i in l do print(i) end
print('--- Iter mul9')
for i in range(#l) do print(i, l[i]) end
print("--- Mapgen")
PI = 3.14159265358979
@ -25,22 +38,59 @@ d = {
}
sublist = [1 1 2 3 5 8],
["this time with spaces"] = PI*2,
[1 + 5] = 1 + 5
[1 + 5] = 1 + 5,
[1 + 9] = 1 + 9
}
print(d)
print('--- Map iter')
for i in d do print(i, d[i]) end
print('--- try')
func bad(x)
x.c()
print(x)
return x.c()
end
test1 = {c = func() end}
test1 = {c = func() return 15 end}
test2 = {}
print(try(bad, test1))
print(try(bad, test2))
print(bad(test1))
--print(bad(test2))
print('--- Indexing')
print(d["integer"])
print(d.integer)
d.integer += 5
print(d.integer)
print('--- Function binding')
func outer(a)
func inner(b)
return a+b
end
inner.a = a
return inner
end
i = outer(5)
print(i(3), i(4), i(5))
j = outer(8)
print(j(3), j(4), j(5))
print('--- Iterators')
func myiter()
if i>10 then return StopIteration end
i+=1
return i-1
end
myiter.i = 1
for i in myiter do print(i) end
Loading…
Cancel
Save