diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/frame.c | 152 | ||||
| -rw-r--r-- | src/core/frame.h | 68 | ||||
| -rw-r--r-- | src/core/interpret.c | 1255 | ||||
| -rw-r--r-- | src/core/interpret.h | 80 | ||||
| -rw-r--r-- | src/core/lambda.c | 98 | ||||
| -rw-r--r-- | src/core/lambda.h | 55 | ||||
| -rw-r--r-- | src/core/promise.c | 60 | ||||
| -rw-r--r-- | src/core/promise.h | 49 | ||||
| -rw-r--r-- | src/core/scanner.c | 169 | ||||
| -rw-r--r-- | src/core/scanner.h | 42 | ||||
| -rw-r--r-- | src/core/token.c | 369 | ||||
| -rw-r--r-- | src/core/token.h | 172 | ||||
| -rw-r--r-- | src/core/tools.c | 64 | ||||
| -rw-r--r-- | src/core/tools.h | 42 | ||||
| -rw-r--r-- | src/core/variable.c | 59 | ||||
| -rw-r--r-- | src/core/variable.h | 52 |
16 files changed, 1144 insertions, 1642 deletions
diff --git a/src/core/frame.c b/src/core/frame.c new file mode 100644 index 0000000..9143a0d --- /dev/null +++ b/src/core/frame.c @@ -0,0 +1,152 @@ +/*:* + *: File: ./src/core/frame.c + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: Redistribution and use in source and binary forms, with or without modi- + *: fication, are permitted provided that the following conditions are met: + *: * Redistributions of source code must retain the above copyright + *: notice, this list of conditions and the following disclaimer. + *: * Redistributions in binary form must reproduce the above copyright + *: notice, this list of conditions and the following disclaimer in the + *: documentation and/or other materials provided with the distribution. + *: * Neither the name of buetow.org nor the names of its contributors may + *: be used to endorse or promote products derived from this software + *: without specific prior written permission. + *: + *: THIS SOFTWARE IS PROVIDED BY PAUL C. BUETOW AS IS'' AND ANY EXPRESS OR + *: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + *: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + *: DISCLAIMED. IN NO EVENT SHALL PAUL C. BUETOW BE LIABLE FOR ANY DIRECT, + *: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + *: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + *: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + *: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + *: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + *: IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + *: POSSIBILITY OF SUCH DAMAGE. + *:*/ + +#include "frame.h" +#include "lambda.h" +#include "variable.h" + +unsigned _I_FRAME_ID_COUNT = 0; + +Symbol* +symbol_new(SymbolType st, void *p_val) { + Symbol *p_symbol = malloc(sizeof(Symbol)); + + p_symbol->st = st; + p_symbol->p_val = p_val; + + return (p_symbol); +} + +void +symbol_delete(Symbol *p_symbol) { + switch (p_symbol->st) { + case ST_LAMBDA: + lambda_delete(p_symbol->p_val); + break; + case ST_VARIABLE: + variable_delete(p_symbol->p_val); + break; + } + + free(p_symbol); +} + +void +symbol_delete_cb(void *p_symbol) { + symbol_delete(p_symbol); +} + +char* +symbol_get_type_name(Symbol *p_symbol) { + switch (p_symbol->st) { + case ST_LAMBDA: + return ("ST_LAMBDA"); + case ST_VARIABLE: + return ("ST_VARIABLE"); + } + + return ("ST_UNKNOWN"); +} + +Frame* +frame_new(Frame *p_parent_frame) { + Frame *p_frame = malloc(sizeof(Frame)); + + p_frame->p_parent_frame = p_parent_frame; + p_frame->p_hash_symbols = hash_new(8); + p_frame->i_frame_id = _I_FRAME_ID_COUNT++; + + return (p_frame); +} + +void +frame_delete(Frame *p_frame) { + Hash *p_hash_symbols = p_frame->p_hash_symbols; + + hash_iterate(p_hash_symbols, symbol_delete_cb); + hash_delete(p_hash_symbols); +} + +_Bool +frame_add_symbol(Frame *p_frame, char *c_name, SymbolType st, void *p_val) { + Hash *p_hash_symbols = p_frame->p_hash_symbols; + + if (hash_key_exists(p_hash_symbols, c_name)) + return (false); + + + Symbol *p_symbol = symbol_new(st, p_val); + hash_insert(p_hash_symbols, c_name, p_symbol); + + return (true); +} + +Symbol* +frame_get_symbol(Frame *p_frame, char *c_name) { + void *p_val = hash_get(p_frame->p_hash_symbols, c_name); + + if (!p_val && p_frame->p_parent_frame) + return (frame_get_symbol(p_frame->p_parent_frame, c_name)); + + return (p_val); +} + +void +_symbol_print_cb(void *p_val, char *c_name) { + Symbol *p_symbol = p_val; + switch (p_symbol->st) { + case ST_LAMBDA: + lambda_print(p_symbol->p_val); + break; + case ST_VARIABLE: + variable_print(p_symbol->p_val); + break; + } +} + +void +_frame_print(Frame *p_frame, int i_frame_nr) { + printf("FRAME(id=%u) %d:\n", p_frame->i_frame_id, i_frame_nr); + + Hash *p_hash_symbols = p_frame->p_hash_symbols; + hash_iterate_key(p_hash_symbols, _symbol_print_cb); + + if (p_frame->p_parent_frame) + _frame_print(p_frame->p_parent_frame, i_frame_nr + 1); +} + +void +frame_print(Frame *p_frame) { + _frame_print(p_frame, 0); +} diff --git a/src/core/frame.h b/src/core/frame.h new file mode 100644 index 0000000..d1e01f5 --- /dev/null +++ b/src/core/frame.h @@ -0,0 +1,68 @@ +/*:* + *: File: ./src/core/frame.h + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: Redistribution and use in source and binary forms, with or without modi- + *: fication, are permitted provided that the following conditions are met: + *: * Redistributions of source code must retain the above copyright + *: notice, this list of conditions and the following disclaimer. + *: * Redistributions in binary form must reproduce the above copyright + *: notice, this list of conditions and the following disclaimer in the + *: documentation and/or other materials provided with the distribution. + *: * Neither the name of buetow.org nor the names of its contributors may + *: be used to endorse or promote products derived from this software + *: without specific prior written permission. + *: + *: THIS SOFTWARE IS PROVIDED BY PAUL C. BUETOW AS IS'' AND ANY EXPRESS OR + *: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + *: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + *: DISCLAIMED. IN NO EVENT SHALL PAUL C. BUETOW BE LIABLE FOR ANY DIRECT, + *: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + *: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + *: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + *: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + *: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + *: IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + *: POSSIBILITY OF SUCH DAMAGE. + *:*/ + +#ifndef FRAME_H +#define FRAME_H + +#include "../defines.h" +#include "../data/hash.h" + +typedef enum { + ST_LAMBDA, + ST_VARIABLE, +} SymbolType; + +typedef struct { + SymbolType st; + void *p_val; +} Symbol; + +typedef struct _Frame { + struct _Frame *p_parent_frame; + Hash *p_hash_symbols; + unsigned i_frame_id; +} Frame; + +Symbol* symbol_new(SymbolType st, void *p_val); +void symbol_delete(Symbol *p_symbol); +void symbol_delete_cb(void *p_symbol); +char* symbol_get_type_name(Symbol *p_symbol); + +Frame* frame_new(Frame *p_parent_frame); +void frame_delete(Frame *p_frame); +_Bool frame_add_symbol(Frame *p_frame, char *c_name, SymbolType st, void *p_val); +Symbol *frame_get_symbol(Frame *p_frame, char *c_name); +void frame_print(Frame *p_frame); + +#endif diff --git a/src/core/interpret.c b/src/core/interpret.c index 49fab69..28239ef 100644 --- a/src/core/interpret.c +++ b/src/core/interpret.c @@ -1,14 +1,13 @@ /*:* *: File: ./src/core/interpret.c - *: A simple interpreter - *: - *: WWW : http://fype.buetow.org - *: AUTHOR : http://paul.buetow.org - *: E-Mail : fype at dev.buetow.org - *: - *: Copyright (c) 2005 - 2009, Dipl.-Inform. (FH) Paul C. Buetow - *: All rights reserved. - *: + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: *: Redistribution and use in source and binary forms, with or without modi- *: fication, are permitted provided that the following conditions are met: *: * Redistributions of source code must retain the above copyright @@ -16,1057 +15,365 @@ *: * Redistributions in binary form must reproduce the above copyright *: notice, this list of conditions and the following disclaimer in the *: documentation and/or other materials provided with the distribution. - *: * Neither the name of buetow.org nor the names of its contributors may - *: be used to endorse or promote products derived from this software + *: * Neither the name of buetow.org nor the names of its contributors may + *: be used to endorse or promote products derived from this software *: without specific prior written permission. - *: - *: THIS SOFTWARE IS PROVIDED BY PAUL C. BUETOW AS IS'' AND ANY EXPRESS OR - *: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + *: + *: THIS SOFTWARE IS PROVIDED BY PAUL C. BUETOW AS IS'' AND ANY EXPRESS OR + *: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED *: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - *: DISCLAIMED. IN NO EVENT SHALL PAUL C. BUETOW BE LIABLE FOR ANY DIRECT, - *: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - *: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - *: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + *: DISCLAIMED. IN NO EVENT SHALL PAUL C. BUETOW BE LIABLE FOR ANY DIRECT, + *: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + *: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + *: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - *: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - *: IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + *: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + *: IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *: POSSIBILITY OF SUCH DAMAGE. *:*/ #include "interpret.h" +#include "promise.h" +#include "variable.h" +#include "tools.h" -#include "../defines.h" -#include "convert.h" -#include "functions.h" -#include "symbol.h" - -#define _INTERPRET_ERROR(m,t) \ - ERROR(\ - "%s: Interpret error in %s line %d pos %d near '%s'", m, \ - token_get_filename(t), \ - token_get_line_nr(t), \ - token_get_pos_nr(t), \ - token_get_val(t) \ - ) - -#define _CHECK if (p_interpret->p_token == NULL) return (0); -#define _HAS_NEXT listiterator_has_next(p_interpret->p_iter) -#define _NEXT_ORG _next(p_interpret); -#define _NEXT if (!_next(p_interpret)) { return (2); } -#define _NEXT2 _NEXT _NEXT -#define _NEXT_TT _next_tt(p_interpret) -#define _SKIP _next(p_interpret); - -int _block(Interpret *p_interpret); -int _block_get(Interpret *p_interpret, List *p_list_block); -int _block_skip(Interpret *p_interpret); -int _compare(Interpret *p_interpret); -int _control(Interpret *p_interpret); -int _expression(Interpret *p_interpret); -int _expression_(Interpret *p_interpret); -int _expression_get(Interpret *p_interpret, List *p_list_block); -int _func_decl(Interpret *p_interpret); -int _next(Interpret *p_interpret); -int _proc_decl(Interpret *p_interpret); -int _product(Interpret *p_interpret); -int _product2(Interpret *p_interpret); -int _program(Interpret *p_interpret); -int _statement(Interpret *p_interpret); -int _sum(Interpret *p_interpret); -int _term(Interpret *p_interpret); -int _var_assign(Interpret *p_interpret); -int _var_decl(Interpret *p_interpret); -int _var_list(Interpret *p_interpret); -void _print_lookahead(Interpret *p_interpret); +void _eval(Interpret *p_inter); Interpret* -interpret_new(List *p_list_token, Hash *p_hash_syms) { - Interpret *p_interpret = malloc(sizeof(Interpret)); +interpret_new(List *p_list_token) { + Interpret *p_inter = malloc(sizeof(Interpret)); - /* No subprocess */ - if (p_hash_syms != NULL) { - p_interpret->p_scope = scope_new(p_hash_syms); - p_interpret->b_scope_delete = true; + p_inter->p_frame = frame_new(NULL); - /* Subprocess */ - } else { - p_interpret->p_scope = NULL; - p_interpret->b_scope_delete = false; - } - - p_interpret->p_list_token = p_list_token; - p_interpret->p_stack = stack_new(); - p_interpret->tt = TT_NONE; - p_interpret->p_token = NULL; - p_interpret->tt_prev = TT_NONE; - p_interpret->p_token_prev = NULL; - p_interpret->p_token_temp = NULL; - p_interpret->ct = CONTROL_NONE; - - return (p_interpret); -} - -void -interpret_delete(Interpret *p_interpret) { - if (!p_interpret) - return; - - if (p_interpret->b_scope_delete) - scope_delete(p_interpret->p_scope); - - stack_delete(p_interpret->p_stack); - free(p_interpret); -} - -void -_print_lookahead(Interpret *p_interpret) { - ListIterator *p_iter = p_interpret->p_iter; - ListIteratorState *p_state = listiterator_get_state(p_iter); + p_inter->p_list_token = p_list_token; + p_inter->p_token = NULL; - printf("LOOLAHEAD:\n"); + p_inter->i_pcount = 0; - token_print(p_interpret->p_token); - printf("\n"); + p_inter->b_is_lambda_interpretation = false; + p_inter->p_lambda = NULL; - while (listiterator_has_next(p_iter)) { - Token *p_token = listiterator_next(p_iter); - token_print(p_token); - printf("\n"); - } - - listiterator_set_state(p_iter, p_state); - listiteratorstate_delete(p_state); + return (p_inter); } -int -_next(Interpret *p_interpret) { - if (listiterator_has_next(p_interpret->p_iter)) { - p_interpret->p_token_prev = p_interpret->p_token; - p_interpret->tt_prev = p_interpret->tt; - - p_interpret->p_token = listiterator_next(p_interpret->p_iter); - p_interpret->tt = token_get_tt(p_interpret->p_token); - return (1); - } +Interpret* +interpret_new_lambda(Interpret *p_inter, Lambda *p_lambda) { + Interpret *p_inter_up = malloc(sizeof(Interpret)); + p_inter_up->p_frame = frame_new(p_lambda->p_frame); + p_inter_up->p_list_token = NULL; + p_inter_up->p_token = NULL; + p_inter_up->i_pcount = 0; - p_interpret->p_token = NULL; - p_interpret->tt = TT_NONE; - //printf("==>\n"); + p_inter_up->b_is_lambda_interpretation = true; + p_inter_up->p_lambda = p_lambda; - return (0); + return (p_inter_up); } -TokenType -_next_tt(Interpret *p_interpret) { - if (listiterator_has_next(p_interpret->p_iter)) { - Token *p_token = listiterator_current(p_interpret->p_iter); - return (token_get_tt(p_token)); - } - - return (TT_NONE); +void +interpret_delete(Interpret *p_inter) { + frame_delete(p_inter->p_frame); + free(p_inter); } -int -_program(Interpret *p_interpret) { - _CHECK TRACK +void +interpret_run(PBSc *p_fype) { + Interpret *p_inter = + interpret_new(p_fype->p_list_token); - while (_statement(p_interpret) == 1) - garbage_collect(); + _eval(p_inter); - return (1); + interpret_delete(p_inter); } -int -_var_decl(Interpret *p_interpret) { - _CHECK TRACK - - switch (p_interpret->tt) { - case TT_MY: - { - if (_NEXT_TT != TT_IDENT) - _INTERPRET_ERROR("'my' expects identifier", p_interpret->p_token); - - _NEXT - - Token *p_token_ident = p_interpret->p_token; - - _var_assign(p_interpret); - _var_list(p_interpret); - - if (p_interpret->tt == TT_SEMICOLON) { - _NEXT - return (1); - - } else if (p_interpret->p_token != NULL) { - _INTERPRET_ERROR("Expected ';'", p_interpret->p_token); - - } else { - _INTERPRET_ERROR("Expected ';' after", p_token_ident); +void +_def(Interpret *p_inter, Token *p_token, ListIterator *p_iter) { + Frame *p_frame = p_inter->p_frame; + _Bool b_success; + + if (!listiterator_has_next(p_iter)) + ERROR_EOB; + + p_token = listiterator_next(p_iter); + char *c_name; + + if (p_token->tt_cur == TT_IDENT) { + c_name = p_token->c_val; + + ListElem *p_listelem = listiterator_current_elem(p_iter); + + if (!listiterator_has_next(p_iter)) + ERROR_EOB; + + p_token = listiterator_next(p_iter); + + switch (p_token->tt_cur) { + case TT_PARANT_L: { + tool_skip_block(p_iter, 0); + ListElem *p_listelem_end = listiterator_current_elem(p_iter); + Lambda *p_lambda = lambda_new( + c_name, + NULL, + p_listelem, + p_listelem_end, + p_inter->p_frame); + //printf("::1\n"); + b_success = frame_add_symbol(p_frame, c_name, ST_LAMBDA, p_lambda); } - } - default: break; - } - - return (0); -} - -int -_var_assign(Interpret *p_interpret) { - _CHECK TRACK - - if (p_interpret->tt == TT_IDENT) { - Token *p_token = p_interpret->p_token; - _NEXT - - char *c_name = token_get_val(p_token); - if (scope_exists(p_interpret->p_scope, c_name)) { - _INTERPRET_ERROR("Symbol already defined", p_token); - } - - if (p_interpret->tt == TT_ASSIGN) { - _NEXT - - if (p_interpret->tt == TT_VID) { - _NEXT - if (p_interpret->tt != TT_IDENT) - _INTERPRET_ERROR("Expected identifier", p_interpret->p_token); - - char *c_name_ = token_get_val(p_interpret->p_token); - Symbol *p_symbol = scope_get(p_interpret->p_scope, c_name_); - - if (p_symbol == NULL) - _INTERPRET_ERROR("No such symbol", p_interpret->p_token); - - symbol_ref_up(p_symbol); - scope_newset(p_interpret->p_scope, c_name, p_symbol); - _NEXT - - } else { - Stack *p_stack = p_interpret->p_stack; - p_interpret->p_stack = stack_new(); - - if (_expression_(p_interpret)) { - function_process_buildin(p_interpret, p_token, - p_interpret->p_stack); - - stack_merge(p_stack, p_interpret->p_stack); - stack_delete(p_interpret->p_stack); - p_interpret->p_stack = p_stack; - - p_token = stack_top(p_interpret->p_stack); - Symbol *p_symbol = symbol_new(SYM_VARIABLE, p_token); - scope_newset(p_interpret->p_scope, c_name, p_symbol); - } else { - return (0); - } - } - } else { - Token *p_token = token_new_integer(0); - Symbol *p_symbol = symbol_new(SYM_VARIABLE, p_token); - scope_newset(p_interpret->p_scope, c_name, p_symbol); - } - } - - return (1); -} - -int -_var_list(Interpret *p_interpret) { - _CHECK TRACK - - if (p_interpret->tt == TT_COMMA) { - _NEXT - _var_assign(p_interpret); - _var_list(p_interpret); - } - - return (1); -} - -int -_block_get(Interpret *p_interpret, List *p_list_block) { - if (p_interpret->tt != TT_PARANT_CL) - _INTERPRET_ERROR("Expected '{'", p_interpret->p_token); - _NEXT - - int i_num_parant = 0; - - for (;;) { - if (p_interpret->tt == TT_PARANT_CL) { - ++i_num_parant; - - } else if (p_interpret->tt == TT_PARANT_CR) { - if (--i_num_parant == -1) { - _NEXT - break; /* for */ - } + case TT_IDENT: { + Variable *p_variable = variable_new( + c_name, + p_token, + p_inter->p_frame); + b_success = frame_add_symbol(p_frame, + c_name, ST_VARIABLE, p_variable); + if (!listiterator_has_next(p_iter)) + ERROR_EOB; + Token *p_token2 = listiterator_next(p_iter); + if (p_token2->tt_cur != TT_PARANT_R) + ERROR_INTERPRET("Expected ) or (", p_token); } - - list_add_back(p_list_block, p_interpret->p_token); - - _NEXT - } - -#ifdef DEBUG_BLOCK_GET - printf("DEBUG::BLOCK::GET: ====>\n"); - list_iterate(p_list_block, token_print_cb); - printf("DEBUG::BLOCK::GET: <====\n"); -#endif /* DEBUG_BLOCK_GET */ - - return (1); -} - -int -_expression_get(Interpret *p_interpret, List *p_list_expression) { - for (;;) { - if (p_interpret->tt == TT_PARANT_CL) { - break; /* for */ + break; + default: + ERROR_INTERPRET("Expected ( or identifier", p_token); } - list_add_back(p_list_expression, p_interpret->p_token); + } else if (p_token->tt_cur == TT_PARANT_L) { + List *p_list_args = list_new(); - _NEXT - } + if (!listiterator_has_next(p_iter)) + ERROR_INTERPRET("Expected identifier", p_token); -#ifdef DEBUG_EXPRESSION_GET - printf("DEBUG::EXPRESSION::GET: ====>\n"); - list_iterate(p_list_expression, token_print_cb); - printf("DEBUG::EXPRESSION::GET: <====\n"); -#endif /* DEBUG_EXPRESSION_GET */ + p_token = listiterator_next(p_iter); + if (p_token->tt_cur != TT_IDENT) + ERROR_INTERPRET("Expected identifier", p_token); - return (1); -} + c_name = p_token->c_val; + while (listiterator_has_next(p_iter)) { + p_token = listiterator_next(p_iter); -int -_block_skip(Interpret *p_interpret) { - if (p_interpret->tt != TT_PARANT_CL) - _INTERPRET_ERROR("Expected '{'", p_interpret->p_token); - _NEXT - - int i_num_parant = 0; - - for (;;) { - if (p_interpret->tt == TT_PARANT_CL) { - ++i_num_parant; + if (p_token->tt_cur != TT_IDENT) { + if (p_token->tt_cur != TT_PARANT_R) + ERROR_INTERPRET("Expected identifier or )", p_token); + break; - } else if (p_interpret->tt == TT_PARANT_CR) { - if (--i_num_parant == -1) { - _NEXT - break; /* for */ + } else { + list_add_back(p_list_args, p_token->c_val); } } - _NEXT - } - - return (1); -} - -int -_proc_decl(Interpret *p_interpret) { - _CHECK TRACK - - if (p_interpret->tt == TT_PROC) { - _NEXT - - if (p_interpret->tt != TT_IDENT) - _INTERPRET_ERROR("Expected identifier", p_interpret->p_token); - - Token *p_token_ident = p_interpret->p_token; - _NEXT - - if (scope_exists(p_interpret->p_scope, token_get_val(p_token_ident))) { - _INTERPRET_ERROR("Symbol already defined", p_token_ident); - } - - List *p_list_proc = list_new(); - - if (_block_get(p_interpret, p_list_proc)) { - - Symbol *p_symbol = symbol_new(SYM_PROCEDURE, p_list_proc); - scope_newset(p_interpret->p_scope, token_get_val(p_token_ident), - p_symbol); - - return (1); - } - - list_delete(p_list_proc); - } - - return (0); -} - -int -_func_decl(Interpret *p_interpret) { - _CHECK TRACK - - if (p_interpret->tt == TT_FUNC) { - _NEXT - - if (p_interpret->tt != TT_IDENT) - _INTERPRET_ERROR("Expected identifier", p_interpret->p_token); - - Token *p_token_ident = p_interpret->p_token; - _NEXT - - if (scope_exists(p_interpret->p_scope, token_get_val(p_token_ident))) { - _INTERPRET_ERROR("Symbol already defined", p_token_ident); - } - - List *p_list_proc = list_new(); - - if (_block_get(p_interpret, p_list_proc)) { - - Symbol *p_symbol = symbol_new(SYM_FUNCTION, p_list_proc); - scope_newset(p_interpret->p_scope, token_get_val(p_token_ident), - p_symbol); - - return (1); - } - - list_delete(p_list_proc); - } - - return (0); -} - -int -_statement(Interpret *p_interpret) { - _CHECK TRACK - - for (int i = 0; i < 2; ++i) { - if (_proc_decl(p_interpret)) return (1); - if (_func_decl(p_interpret)) return (1); - if (_var_decl(p_interpret)) return (1); - if (_control(p_interpret)) return (1); - if (_expression(p_interpret)) return (1); - if (_block(p_interpret)) return (1); - } - - return (0); -} - -int -_block(Interpret *p_interpret) { - if (p_interpret->tt == TT_PARANT_CL) { - List *p_list_block = list_new(); - - if (_block_get(p_interpret, p_list_block)) { - scope_up(p_interpret->p_scope); - interpret_subprocess(p_interpret, p_list_block); - scope_down(p_interpret->p_scope); - list_delete(p_list_block); - return (1); - } - - list_delete(p_list_block); + ListElem *p_listelem = listiterator_next_elem(p_iter); + //printf("::2\n"); + tool_skip_block(p_iter, 2); + ListElem *p_listelem_end = listiterator_current_elem(p_iter); + + Lambda *p_lambda = lambda_new( + c_name, + p_list_args, + p_listelem, + p_listelem_end, + p_inter->p_frame); + b_success = frame_add_symbol(p_frame, c_name, ST_LAMBDA, p_lambda); + } else { + ERROR_INTERPRET("Expected identifier or (", p_token); } - return (0); + if (!b_success) + ERROR("Forbidden to redef symbol \"%s\" @ current frame", c_name); } -int -_expression(Interpret *p_interpret) { - _CHECK TRACK - - if (_expression_(p_interpret)) { - TokenType tt = p_interpret->tt; - if (tt == TT_SEMICOLON || tt == TT_NONE) { - _NEXT - - } else { - _INTERPRET_ERROR("Expected ';'", p_interpret->p_token); +void +_say(Interpret *p_inter, Token *p_token, ListIterator *p_iter) { + while (listiterator_has_next(p_iter)) { + Token *p_token = listiterator_next(p_iter); + switch (p_token->tt_cur) { + case TT_IDENT: + case TT_INTEGER: + case TT_STRING: + printf("%s\n", p_token->c_val); + break; + case TT_PARANT_L: + ERROR("Not yet implemented"); + break; + case TT_PARANT_R: + return; + NO_DEFAULT; } - - stack_clear(p_interpret->p_stack); - return (1); } - - return (0); -} - -int -_expression_(Interpret *p_interpret) { - return (_compare(p_interpret)); } -int -_control(Interpret *p_interpret) { - _CHECK TRACK - - Token *p_token = p_interpret->p_token; - - switch (p_interpret->tt) { - case TT_IF: - case TT_IFNOT: - { - TokenType tt = p_interpret->tt; - _NEXT - if (_expression_(p_interpret)) { - Token *p_token_top = stack_pop(p_interpret->p_stack); - List *p_list_block = list_new(); - _block_get(p_interpret, p_list_block); - int ret = 0; - - switch (tt) { - case TT_IF: - if (convert_to_integer_get(p_token_top)) { - scope_up(p_interpret->p_scope); - ret = interpret_subprocess(p_interpret, p_list_block); - scope_down(p_interpret->p_scope); +void +_eval_lambda(Interpret *p_inter, Lambda *p_lambda, ListIterator *p_iter) { + Interpret *p_inter_local = interpret_new_lambda(p_inter, p_lambda); + Frame *p_frame_local = p_inter_local->p_frame; + ListIterator *p_iter_args = NULL; + + + if (p_lambda->p_list_args) + p_iter_args = listiterator_new(p_lambda->p_list_args); + + Token *p_token = listiterator_current(p_iter); + + if (p_iter_args) { + while (listiterator_has_next(p_iter_args)) { + char *c_name = listiterator_next(p_iter_args); + + if (!listiterator_has_next(p_iter)) + ERROR_EOB; + ListElem *p_listelem = listiterator_current_elem(p_iter); + p_token = listiterator_next(p_iter); + + switch (p_token->tt_cur) { + case TT_PARANT_L: { + //printf("::3\n"); + tool_skip_block(p_iter, 1 ); + ListElem *p_listelem_end = listiterator_current_elem(p_iter); + Lambda *p_lambda_ = lambda_new( + c_name, + NULL, + p_listelem, + p_listelem_end, + p_frame_local); + if (!frame_add_symbol(p_frame_local, + c_name, + ST_LAMBDA, + p_lambda_)) { + printf("Illegal reuse of parameter '%s' @ function '%s'", + c_name, p_lambda->c_name); + ERROR_INTERPRET(". Error binding local lambda", p_token); } + } + break; + case TT_PARANT_R: + ERROR_INTERPRET("Didn't expect ) here", p_token); break; - case TT_IFNOT: - if (!convert_to_integer_get(p_token_top)) { - scope_up(p_interpret->p_scope); - ret = interpret_subprocess(p_interpret, p_list_block); - scope_down(p_interpret->p_scope); + default: { + Variable *p_variable = variable_new(c_name, + p_token, + p_frame_local); + if (!frame_add_symbol(p_frame_local, + c_name, + ST_VARIABLE, + p_variable)) { + printf("Illegal reuse of parameter '%s' @ function '%s'\n", + c_name, p_lambda->c_name); + frame_print(p_frame_local); + ERROR_INTERPRET("Fatal", p_token); } - break; - NO_DEFAULT; } - - list_delete(p_list_block); - return (1); - - } else { - _INTERPRET_ERROR("Expected expression after control keyword", p_token); - } - } - break; - case TT_WHILE: - case TT_UNTIL: - { - TokenType tt = p_interpret->tt; - List *p_list_expr = list_new(), *p_list_block = list_new(); - _Bool b_flag = true; - - _NEXT - - _expression_get(p_interpret, p_list_expr); - _block_get(p_interpret, p_list_block); - Token *p_token_backup = p_interpret->p_token; - - do { - Stack *p_stack_backup = p_interpret->p_stack; - p_interpret->p_stack = stack_new(); - - ListIterator *p_iter_backup = p_interpret->p_iter; - p_interpret->p_iter = listiterator_new(p_list_expr); - - _NEXT - - /* Dont use if here, because we want to check the p_itnerpret->ct */ - if (_expression_(p_interpret)) { - Token *p_token_top = stack_pop(p_interpret->p_stack); - - if (p_token_top == NULL) { - printf("FOO\n"); - exit(0); - } - if (tt == TT_WHILE) { - if (convert_to_integer_get(p_token_top)) { - scope_up(p_interpret->p_scope); - interpret_subprocess(p_interpret, p_list_block); - scope_down(p_interpret->p_scope); - - } else { - b_flag = false; - } - - } else if (tt == TT_UNTIL) { - if (!convert_to_integer_get(p_token_top)) { - scope_up(p_interpret->p_scope); - interpret_subprocess(p_interpret, p_list_block); - scope_down(p_interpret->p_scope); - - } else { - b_flag = false; - } - } - - /* - switch (p_interpret->ct) { - case CONTROL_BREAK: - p_interpret->ct = CONTROL_NONE; - b_flag = false; - break; - case CONTROL_NEXT: - p_interpret->ct = CONTROL_NONE; - break; - NO_DEFAULT; - } - */ - |
