summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/frame.c152
-rw-r--r--src/core/frame.h68
-rw-r--r--src/core/interpret.c1255
-rw-r--r--src/core/interpret.h80
-rw-r--r--src/core/lambda.c98
-rw-r--r--src/core/lambda.h55
-rw-r--r--src/core/promise.c60
-rw-r--r--src/core/promise.h49
-rw-r--r--src/core/scanner.c169
-rw-r--r--src/core/scanner.h42
-rw-r--r--src/core/token.c369
-rw-r--r--src/core/token.h172
-rw-r--r--src/core/tools.c64
-rw-r--r--src/core/tools.h42
-rw-r--r--src/core/variable.c59
-rw-r--r--src/core/variable.h52
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);
-
-