diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/convert.c | 185 | ||||
| -rw-r--r-- | src/core/convert.h | 53 | ||||
| -rw-r--r-- | src/core/function.c | 661 | ||||
| -rw-r--r-- | src/core/function.h | 50 | ||||
| -rw-r--r-- | src/core/garbage.c | 136 | ||||
| -rw-r--r-- | src/core/garbage.h | 54 | ||||
| -rw-r--r-- | src/core/interpret.c | 946 | ||||
| -rw-r--r-- | src/core/interpret.h | 75 | ||||
| -rw-r--r-- | src/core/scanner.c | 391 | ||||
| -rw-r--r-- | src/core/scanner.h | 71 | ||||
| -rw-r--r-- | src/core/scope.c | 150 | ||||
| -rw-r--r-- | src/core/scope.h | 59 | ||||
| -rw-r--r-- | src/core/symbol.c | 66 | ||||
| -rw-r--r-- | src/core/symbol.h | 64 | ||||
| -rw-r--r-- | src/core/token.c | 380 | ||||
| -rw-r--r-- | src/core/token.h | 183 |
16 files changed, 3524 insertions, 0 deletions
diff --git a/src/core/convert.c b/src/core/convert.c new file mode 100644 index 0000000..0d63619 --- /dev/null +++ b/src/core/convert.c @@ -0,0 +1,185 @@ +/*:* + *: File: ./src/core/convert.c + *: A simple interpreter + *: + *: WWW : http://fype.buetow.org + *: E-Mail : fype@dev.buetow.org + *: + *: Copyright (c) 2005 2006 2007 2008, Paul Buetow (http://www.pblabs.net) + *: All rights reserved. + *: + *: 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 P. B. Labs 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 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 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 "convert.h" + +void +convert_to_integer(Token *p_token) { + switch (token_get_tt(p_token)) { + case TT_INTEGER: + break; + case TT_DOUBLE: + token_set_tt(p_token, TT_INTEGER); + token_set_ival(p_token, (int)token_get_dval(p_token)); + break; + case TT_STRING: + token_set_tt(p_token, TT_INTEGER); + token_set_ival(p_token, atoi(token_get_val(p_token))); + break; + default: + ERROR("Ouups(%s)", tt_get_name(token_get_tt(p_token))); + break; + } +} + +int +convert_to_integer_get(Token *p_token) { + switch (token_get_tt(p_token)) { + case TT_INTEGER: + return (token_get_ival(p_token)); + case TT_DOUBLE: + return ((int) token_get_dval(p_token)); + case TT_STRING: + return (atoi(token_get_val(p_token))); + default: + ERROR("Ouups(%s)", tt_get_name(token_get_tt(p_token))); + } + + return (0); /* Never reach this point */ +} + +void +convert_to_double(Token *p_token) { + switch (token_get_tt(p_token)) { + case TT_INTEGER: + token_set_tt(p_token, TT_DOUBLE); + token_set_dval(p_token, token_get_ival(p_token)); + break; + case TT_DOUBLE: + break; + case TT_STRING: + token_set_tt(p_token, TT_DOUBLE); + token_set_dval(p_token, atof(token_get_val(p_token))); + break; + default: + token_print_val(p_token); + ERROR("Datatype conversion error '%s'", token_get_val(p_token)); + break; + } +} + +void +convert_to_string(Token *p_token) { + switch (token_get_tt(p_token)) { + case TT_INTEGER: + { + token_set_tt(p_token, TT_STRING); + char c_tmp[1024]; + sprintf(c_tmp, "%d", token_get_ival(p_token)); + int i_len = strlen(c_tmp); + p_token->c_val = realloc(p_token->c_val, sizeof(char) * (i_len + 1)); + strcpy(p_token->c_val, c_tmp); + p_token->c_val[i_len] = 0; + } + break; + case TT_DOUBLE: + { + token_set_tt(p_token, TT_STRING); + char c_tmp[1024]; + sprintf(c_tmp, "%f", token_get_dval(p_token)); + int i_len = strlen(c_tmp); + p_token->c_val = realloc(p_token->c_val, sizeof(char) * (i_len + 1)); + strcpy(p_token->c_val, c_tmp); + p_token->c_val[i_len] = 0; + } + break; + case TT_STRING: + break; + default: + ERROR("Datatype conversion error"); + break; + } +} + +void +convert_to_tt(Token *p_token, TokenType tt) { + switch (tt) { + case TT_INTEGER: + convert_to_integer(p_token); + break; + case TT_DOUBLE: + convert_to_double(p_token); + break; + case TT_STRING: + convert_to_string(p_token); + break; + default: + ERROR("Ouups!"); + } +} + +TokenType +convert_to_highest(Token *p_token1, Token *p_token2) { + TokenType tt_highest = token_get_tt(p_token1); + + if (tt_highest < token_get_tt(p_token2)) { + tt_highest = token_get_tt(p_token2); + + convert_to_tt(p_token1, tt_highest); + + } else { + convert_to_tt(p_token2, tt_highest); + } + + return (tt_highest); +} + +TokenType +convert_function_arg_types_to_highest(Stack *p_stack_args, int i_args) { + + if (i_args <= 0) + i_args = stack_size(p_stack_args); + + StackIterator *p_iter = stackiterator_new(p_stack_args); + TokenType tt_highest = TT_INTEGER; + + for (int i = 0; i < i_args && stackiterator_has_next(p_iter); ++i) { + Token *p_token = stackiterator_next(p_iter); + if (token_get_tt(p_token) > tt_highest) + tt_highest = token_get_tt(p_token); + } + + stackiterator_delete(p_iter); + p_iter = stackiterator_new(p_stack_args); + + for (int i = 0; i < i_args && stackiterator_has_next(p_iter); ++i) { + Token *p_token = stackiterator_next(p_iter); + convert_to_tt(p_token, tt_highest); + } + + stackiterator_delete(p_iter); + + return (tt_highest); +} + diff --git a/src/core/convert.h b/src/core/convert.h new file mode 100644 index 0000000..c4e0b1d --- /dev/null +++ b/src/core/convert.h @@ -0,0 +1,53 @@ +/*:* + *: File: ./src/core/convert.h + *: A simple interpreter + *: + *: WWW : http://fype.buetow.org + *: E-Mail : fype@dev.buetow.org + *: + *: Copyright (c) 2005 2006 2007 2008, Paul Buetow (http://www.pblabs.net) + *: All rights reserved. + *: + *: 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 P. B. Labs 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 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 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 CONVERT_H +#define CONVERT_H + +#include "../defines.h" + +#include "../data/stack.h" + +#include "token.h" + +int convert_to_integer_get(Token *p_token); +void convert_to_integer(Token *p_token); +void convert_to_double(Token *p_token); +void convert_to_string(Token *p_token); +void convert_to_tt(Token *p_token, TokenType tt); +TokenType convert_to_highest(Token *p_token1, Token *p_token2); +TokenType convert_function_arg_types_to_highest(Stack *p_stack_args, int + i_args); + +#endif diff --git a/src/core/function.c b/src/core/function.c new file mode 100644 index 0000000..fd18ba0 --- /dev/null +++ b/src/core/function.c @@ -0,0 +1,661 @@ +/*:* + *: File: ./src/core/function.c + *: A simple interpreter + *: + *: WWW : http://fype.buetow.org + *: E-Mail : fype@dev.buetow.org + *: + *: Copyright (c) 2005 2006 2007 2008, Paul Buetow (http://www.pblabs.net) + *: All rights reserved. + *: + *: 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 P. B. Labs 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 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 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 <stdlib.h> +#include <sys/types.h> +#include <unistd.h> + +#include "function.h" + +#include "convert.h" +#include "scope.h" +#include "symbol.h" + +#define _FUNCTION_ERROR(m,t) \ + ERROR(\ + "%s: Function 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) \ + ) + +void +_process(Interpret *p_interpret, Token *p_token_store, Token *p_token_op, + Token *p_token_next) { + + TokenType tt_op = token_get_tt(p_token_op); + +#ifdef DEBUG_FUNCTION_PROCESS + printf("PROCESS OPERATOR %s\n", tt_get_name(tt_op)); + + token_print(p_token_next); + printf("\n"); + token_print(p_token_store); + printf("\n"); +#endif /* DEBUG_FUNCTION_PROCESS */ + + + switch (tt_op) { + case TT_ASSIGN: + { + Token *p_token_assign = p_interpret->p_token_temp; + TokenType tt_assign = token_get_tt(p_token_assign); + + if (tt_assign != TT_IDENT) { + _FUNCTION_ERROR("Can only assign to symbols", + p_token_store); + } + + Symbol *p_symbol = scope_get(p_interpret->p_scope, + token_get_val(p_token_assign)); + + if (p_symbol == NULL) { + _FUNCTION_ERROR("No such symbol", + p_token_assign); + } + + symbol_set_val(p_symbol, p_token_store); + symbol_set_sym(p_symbol, SYM_VARIABLE); + + return; + } + + break; + NO_DEFAULT; + } + + p_token_next = token_new_copy(p_token_next); + TokenType tt_highest = convert_to_highest(p_token_store, p_token_next); + +#ifdef DEBUG_FUNCTION_PROCESS + printf("===> %s %s %s\n", + tt_get_name(tt_highest), + tt_get_name(tt_op), + tt_get_name(tt_highest)); +#endif /* DEBUG_FUNCTION_PROCESS */ + + switch (tt_op) { + case TT_ADD: + switch (tt_highest) { + case TT_INTEGER: + token_set_ival(p_token_store, + token_get_ival(p_token_next) + + token_get_ival(p_token_store)); + break; + case TT_DOUBLE: + token_set_dval(p_token_store, + token_get_dval(p_token_next) + + token_get_dval(p_token_store)); + case TT_STRING: + token_set_ival(p_token_store, + atoi(token_get_val(p_token_next)) + + atoi(token_get_val(p_token_store))); + token_set_tt(p_token_store, TT_INTEGER); + break; + NO_DEFAULT; + } + break; + case TT_SUB: + switch (tt_highest) { + case TT_INTEGER: + token_set_ival(p_token_store, + token_get_ival(p_token_next) - + token_get_ival(p_token_store)); + break; + case TT_DOUBLE: + token_set_dval(p_token_store, + token_get_dval(p_token_next) - + token_get_dval(p_token_store)); + break; + case TT_STRING: + token_set_ival(p_token_store, + atoi(token_get_val(p_token_next)) - + atoi(token_get_val(p_token_store))); + token_set_tt(p_token_store, TT_INTEGER); + break; + NO_DEFAULT; + } + break; + case TT_MULT: + switch (tt_highest) { + case TT_INTEGER: + token_set_ival(p_token_store, + token_get_ival(p_token_next) * + token_get_ival(p_token_store)); + break; + case TT_DOUBLE: + token_set_dval(p_token_store, + token_get_dval(p_token_next) * + token_get_dval(p_token_store)); + break; + case TT_STRING: + token_set_ival(p_token_store, + atoi(token_get_val(p_token_next)) * + atoi(token_get_val(p_token_store))); + token_set_tt(p_token_store, TT_INTEGER); + break; + NO_DEFAULT; + } + break; + case TT_DIV: + switch (tt_highest) { + case TT_INTEGER: + token_set_ival(p_token_store, + (int) token_get_ival(p_token_next) / + token_get_ival(p_token_store)); + break; + case TT_DOUBLE: + token_set_dval(p_token_store, + token_get_dval(p_token_next) / + token_get_dval(p_token_store)); + break; + case TT_STRING: + token_set_dval(p_token_store, + atof(token_get_val(p_token_next)) / + atof(token_get_val(p_token_store))); + token_set_tt(p_token_store, TT_DOUBLE); + break; + NO_DEFAULT; + } + break; + case TT_EQ: + switch (tt_highest) { + case TT_INTEGER: + token_set_ival(p_token_store, + (int) token_get_ival(p_token_next) == + token_get_ival(p_token_store)); + break; + case TT_DOUBLE: + token_set_ival(p_token_store, + token_get_dval(p_token_next) == + token_get_dval(p_token_store)); + token_set_tt(p_token_store, TT_INTEGER); + break; + case TT_STRING: + token_set_ival(p_token_store, + strcmp(token_get_val(p_token_next), + token_get_val(p_token_store)) == 0); + token_set_tt(p_token_store, TT_INTEGER); + break; + NO_DEFAULT; + } + break; + case TT_NEQ: + switch (tt_highest) { + case TT_INTEGER: + token_set_ival(p_token_store, + (int) token_get_ival(p_token_next) != + token_get_ival(p_token_store)); + break; + case TT_DOUBLE: + token_set_ival(p_token_store, + token_get_dval(p_token_next) != + token_get_dval(p_token_store)); + token_set_tt(p_token_store, TT_INTEGER); + break; + case TT_STRING: + token_set_ival(p_token_store, + strcmp(token_get_val(p_token_next), + token_get_val(p_token_store)) != 0); + token_set_tt(p_token_store, TT_INTEGER); + break; + NO_DEFAULT; + } + break; + case TT_LT: + switch (tt_highest) { + case TT_INTEGER: + token_set_ival(p_token_store, + (int) token_get_ival(p_token_next) < + token_get_ival(p_token_store)); + break; + case TT_DOUBLE: + token_set_ival(p_token_store, + token_get_dval(p_token_next) < + token_get_dval(p_token_store)); + token_set_tt(p_token_store, TT_INTEGER); + break; + case TT_STRING: + token_set_ival(p_token_store, + strcmp(token_get_val(p_token_next), + token_get_val(p_token_store)) < 0); + token_set_tt(p_token_store, TT_INTEGER); + break; + NO_DEFAULT; + } + break; + case TT_GT: + switch (tt_highest) { + case TT_INTEGER: + token_set_ival(p_token_store, + (int) token_get_ival(p_token_next) > + token_get_ival(p_token_store)); + break; + case TT_DOUBLE: + token_set_ival(p_token_store, + token_get_dval(p_token_next) > + token_get_dval(p_token_store)); + token_set_tt(p_token_store, TT_INTEGER); + break; + case TT_STRING: + token_set_ival(p_token_store, + strcmp(token_get_val(p_token_next), + token_get_val(p_token_store)) > 0); + token_set_tt(p_token_store, TT_INTEGER); + break; + NO_DEFAULT; + } + break; + case TT_LE: + switch (tt_highest) { + case TT_INTEGER: + token_set_ival(p_token_store, + (int) token_get_ival(p_token_next) <= + token_get_ival(p_token_store)); + break; + case TT_DOUBLE: + token_set_ival(p_token_store, + token_get_dval(p_token_next) <= + token_get_dval(p_token_store)); + token_set_tt(p_token_store, TT_INTEGER); + break; + case TT_STRING: + token_set_ival(p_token_store, + strcmp(token_get_val(p_token_next), + token_get_val(p_token_store)) <= 0); + token_set_tt(p_token_store, TT_INTEGER); + break; + NO_DEFAULT; + } + break; + case TT_GE: + switch (tt_highest) { + case TT_INTEGER: + token_set_ival(p_token_store, + (int) token_get_ival(p_token_next) >= + token_get_ival(p_token_store)); + break; + case TT_DOUBLE: + token_set_ival(p_token_store, + token_get_dval(p_token_next) >= + token_get_dval(p_token_store)); + token_set_tt(p_token_store, TT_INTEGER); + break; + case TT_STRING: + token_set_ival(p_token_store, + strcmp(token_get_val(p_token_next), + token_get_val(p_token_store)) >= 0); + token_set_tt(p_token_store, TT_INTEGER); + break; + NO_DEFAULT; + } + break; + default: + _FUNCTION_ERROR("No such function/operator", p_token_op); + } + +#ifdef DEBUG_FUNCTION_PROCESS + token_print(p_token_store); + printf("\n\n"); +#endif /* DEBUG_FUNCTION_PROCESS */ + + token_delete(p_token_next); +} + +void +function_process(Interpret *p_interpret, Token *p_token_op, + Stack *p_stack_args, int i_args) { + + Token *p_token_store = token_new_copy(stack_pop(p_stack_args)); + + for (int i = 0; i < i_args -1 && !stack_empty(p_stack_args); ++i) { + Token *p_token_next = stack_pop(p_stack_args); + + _process(p_interpret, p_token_store, p_token_op, p_token_next); + } + + stack_push(p_stack_args, p_token_store); +} + +_Bool +function_is_buildin(Token *p_token_ident) { + if (strcmp("assert", token_get_val(p_token_ident)) == 0) + return (true); + + if (strcmp("decr", token_get_val(p_token_ident)) == 0) + return (true); + + if (strcmp("double", token_get_val(p_token_ident)) == 0) + return (true); + + if (strcmp("end", token_get_val(p_token_ident)) == 0) + return (true); + + if (strcmp("exit", token_get_val(p_token_ident)) == 0) + return (true); + + if (strcmp("fork", token_get_val(p_token_ident)) == 0) + return (true); + + if (strcmp("gc", token_get_val(p_token_ident)) == 0) + return (true); + + if (strcmp("incr", token_get_val(p_token_ident)) == 0) + return (true); + + if (strcmp("integer", token_get_val(p_token_ident)) == 0) + return (true); + + if (strcmp("ln", token_get_val(p_token_ident)) == 0) + return (true); + + if (strcmp("neg", token_get_val(p_token_ident)) == 0) + return (true); + + if (strcmp("no", token_get_val(p_token_ident)) == 0) + return (true); + + if (strcmp("put", token_get_val(p_token_ident)) == 0) + return (true); + + if (strcmp("say", token_get_val(p_token_ident)) == 0) + return (true); + + if (strcmp("string", token_get_val(p_token_ident)) == 0) + return (true); + + if (strcmp("yes", token_get_val(p_token_ident)) == 0) + return (true); + + return (false); +} + +void +function_process_buildin(Interpret *p_interpret, Token *p_token_ident, + Stack *p_stack_args) { + + if (strcmp("assert", token_get_val(p_token_ident)) == 0) { + if (0 == stack_size(p_stack_args)) + _FUNCTION_ERROR("No argument given", p_token_ident); + + Token *p_token = stack_top(p_stack_args); + + switch (token_get_tt(p_token)) { + case TT_INTEGER: + if (token_get_ival(p_token) == 0) + _FUNCTION_ERROR("Assert failed", p_token); + break; + case TT_DOUBLE: + if (token_get_dval(p_token) == 0) + _FUNCTION_ERROR("Assert failed", p_token); + break; + case TT_STRING: + if (atoi(token_get_val(p_token)) == 0) + _FUNCTION_ERROR("Assert failed", p_token); + break; + NO_DEFAULT; + } + + } else if (strcmp("decr", token_get_val(p_token_ident)) == 0) { + if (0 == stack_size(p_stack_args)) + _FUNCTION_ERROR("No argument given", p_token_ident); + + Token *p_token = stack_top(p_stack_args); + switch (token_get_tt(p_token)) { + case TT_INTEGER: + token_set_ival(p_token, token_get_ival(p_token) - 1); + break; + case TT_DOUBLE: + token_set_dval(p_token, token_get_dval(p_token) - 1); + break; + case TT_STRING: + convert_to_integer(p_token); + token_set_ival(p_token, token_get_ival(p_token) - 1); + break; + NO_DEFAULT; + } + + } else if (strcmp("double", token_get_val(p_token_ident)) == 0) { + if (0 == stack_size(p_stack_args)) + _FUNCTION_ERROR("No argument given", p_token_ident); + + Token *p_token = token_new_copy(stack_pop(p_stack_args)); + convert_to_double(p_token); + stack_push(p_stack_args, p_token); + + } else if (strcmp("end", token_get_val(p_token_ident)) == 0) { + exit(0); + + } else if (strcmp("fork", token_get_val(p_token_ident)) == 0) { + Token *p_token = token_new_integer((int) fork()); + stack_push(p_stack_args, p_token); + + } else if (strcmp("gc", token_get_val(p_token_ident)) == 0) { + int i_count = garbage_collect(); + printf("ICOUNT %d\n", i_count); + Token *p_token = token_new_integer(i_count); + stack_push(p_stack_args, p_token); + + } else if (strcmp("exit", token_get_val(p_token_ident)) == 0) { + if (0 == stack_size(p_stack_args)) + _FUNCTION_ERROR("No argument given", p_token_ident); + + Token *p_token = stack_top(p_stack_args); + p_token = token_new_copy(p_token); + convert_to_integer(p_token); + exit(token_get_ival(p_token)); + + } else if (strcmp("incr", token_get_val(p_token_ident)) == 0) { + if (0 == stack_size(p_stack_args)) + _FUNCTION_ERROR("No argument given", p_token_ident); + + Token *p_token = stack_top(p_stack_args); + switch (token_get_tt(p_token)) { + case TT_INTEGER: + token_set_ival(p_token, token_get_ival(p_token) + 1); + break; + case TT_DOUBLE: + token_set_dval(p_token, token_get_dval(p_token) + 1); + break; + case TT_STRING: + convert_to_integer(p_token); + token_set_ival(p_token, token_get_ival(p_token) + 1); + break; + NO_DEFAULT; + } + + } else if (strcmp("integer", token_get_val(p_token_ident)) == 0) { + if (0 == stack_size(p_stack_args)) + _FUNCTION_ERROR("No argument given", p_token_ident); + + Token *p_token = token_new_copy(stack_pop(p_stack_args)); + convert_to_integer(p_token); + stack_push(p_stack_args, p_token); + + } else if (strcmp("ln", token_get_val(p_token_ident)) == 0) { + printf("\n"); + + } else if (strcmp("neg", token_get_val(p_token_ident)) == 0) { + if (0 == stack_size(p_stack_args)) + _FUNCTION_ERROR("No argument given", p_token_ident); + + Token *p_token = token_new_copy(stack_pop(p_stack_args)); + stack_push(p_stack_args, p_token); + + switch (token_get_tt(p_token)) { + case TT_INTEGER: + token_set_ival(p_token, -token_get_ival(p_token)); + break; + case TT_DOUBLE: + token_set_dval(p_token, -token_get_dval(p_token)); + break; + case TT_STRING: + token_set_ival(p_token, -atoi(token_get_val(p_token))); + token_set_tt(p_token, TT_INTEGER); + break; + NO_DEFAULT; + } + + } else if (strcmp("no", token_get_val(p_token_ident)) == 0) { + Token *p_token = NULL; + + if (0 == stack_size(p_stack_args)) { + p_token = token_new_integer(0); + + } else { + p_token = token_new_copy(stack_pop(p_stack_args)); + + switch (token_get_tt(p_token)) { + case TT_INTEGER: + token_set_ival(p_token, !token_get_ival(p_token)); + break; + case TT_DOUBLE: + token_set_dval(p_token, !token_get_dval(p_token)); + break; + case TT_STRING: + token_set_ival(p_token, !atoi(token_get_val(p_token))); + token_set_tt(p_token, TT_INTEGER); + break; + NO_DEFAULT; + } + } + + stack_push(p_stack_args, p_token); + + } else if (strcmp("put", token_get_val(p_token_ident)) == 0) { + StackIterator *p_iter = stackiterator_new(p_stack_args); + while (stackiterator_has_next(p_iter)) { + Token *p_token = stackiterator_next(p_iter); + switch (token_get_tt(p_token)) { + case TT_INTEGER: + printf("%d", token_get_ival(p_token)); + break; + case TT_DOUBLE: + printf("%f", token_get_dval(p_token)); + break; + case TT_STRING: + printf("%s", token_get_val(p_token)); + break; + NO_DEFAULT; + } + } + stackiterator_delete(p_iter); + + } else if (strcmp("say", token_get_val(p_token_ident)) == 0) { + StackIterator *p_iter = stackiterator_new(p_stack_args); + while (stackiterator_has_next(p_iter)) { + Token *p_token = stackiterator_next(p_iter); + switch (token_get_tt(p_token)) { + case TT_INTEGER: + printf("%d", token_get_ival(p_token)); + break; + case TT_DOUBLE: + printf("%f", token_get_dval(p_token)); + break; + case TT_STRING: + printf("%s", token_get_val(p_token)); + break; + NO_DEFAULT; + } + } + stackiterator_delete(p_iter); + printf("\n"); + + } else if (strcmp("string", token_get_val(p_token_ident)) == 0) { + if (0 == stack_size(p_stack_args)) + _FUNCTION_ERROR("No argument given", p_token_ident); + + Token *p_token = token_new_copy(stack_pop(p_stack_args)); + convert_to_string(p_token); + stack_push(p_stack_args, p_token); + + } else if (strcmp("yes", token_get_val(p_token_ident)) == 0) { + Token *p_token = NULL; + + if (0 == stack_size(p_stack_args)) { + p_token = token_new_integer(1); + + } else { + p_token = token_new_copy(stack_pop(p_stack_args)); + token_set_ival(p_token, 1); + token_set_tt(p_token, TT_INTEGER); + + } + + stack_push(p_stack_args, p_token); + } +} + +_Bool +function_is_self_defined(Interpret *p_interpret) { + Symbol *p_symbol = scope_get(p_interpret->p_scope, + token_get_val(p_interpret->p_token)); + + if (p_symbol == NULL) + return (false); + + switch (symbol_get_sym(p_symbol)) { + case SYM_PROCEDURE: + case SYM_FUNCTION: + return (true); + NO_DEFAULT; + } + + return (false); +} + +void +function_process_self_defined(Interpret *p_interpret, Token *p_token_ident) { + Symbol *p_symbol = scope_get(p_interpret->p_scope, + token_get_val(p_token_ident)); + + switch (symbol_get_sym(p_symbol)) { + case SYM_PROCEDURE: + { + List *p_list_token = symbol_get_val(p_symbol); + interpret_subprocess(p_interpret, p_list_token); + } + break; + case SYM_FUNCTION: + { + List *p_list_token = symbol_get_val(p_symbol); + scope_up(p_interpret->p_scope); + interpret_subprocess(p_interpret, p_list_token); + scope_down(p_interpret->p_scope); + } + NO_DEFAULT; + } +} + diff --git a/src/core/function.h b/src/core/function.h new file mode 100644 index 0000000..9f12bb4 --- /dev/null +++ b/src/core/function.h @@ -0,0 +1,50 @@ +/*:* + *: File: ./src/core/function.h + *: A simple interpreter + *: + *: WWW : http://fype.buetow.org + *: E-Mail : fype@dev.buetow.org + *: + *: Copyright (c) 2005 2006 2007 2008, Paul Buetow (http://www.pblabs.net) + *: All rights reserved. + *: + *: 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 P. B. Labs 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 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 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 FUNCTION_H +#define FUNCTION_H + +#include "token.h" + +#include "interpret.h" +#include "../data/stack.h" + +void function_process(Interpret *p_interp, Token *p_token_op, Stack + *p_stack_args, int i_args); +_Bool function_is_buildin(Token *p_token_ident); +void function_process_buildin(Interpret *p_interpret, Token *p_token_ident, Stack *p_stack_args); +_Bool function_is_self_defined(Interpret *p_interpret); +void function_process_self_defined(Interpret *p_interpret, Token *p_token_ident); + +#endif /* FUNCTION_H */ diff --git a/src/core/garbage.c b/src/core/garbage.c new file mode 100644 index 0000000..b4dad22 --- /dev/null +++ b/src/core/garbage.c @@ -0,0 +1,136 @@ +/*:* + *: File: ./src/core/garbage.c + *: A simple interpreter + *: + *: WWW : http://fype.buetow.org + *: E-Mail : fype@dev.buetow.org + *: + *: Copyright (c) 2005 2006 2007 2008, Paul Buetow (http://www.pblabs.net) + *: All r |
