From be839900419c7a74c4a46efd279d0ca16b35dc1f Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Thu, 15 May 2008 23:28:07 +0000 Subject: Moved stuff into trunk. --- src/core/scope.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 src/core/scope.c (limited to 'src/core/scope.c') diff --git a/src/core/scope.c b/src/core/scope.c new file mode 100644 index 0000000..f1ca006 --- /dev/null +++ b/src/core/scope.c @@ -0,0 +1,150 @@ +/*:* + *: File: ./src/core/scope.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 "garbage.h" +#include "scope.h" +#include "symbol.h" + +Scope* +scope_new(Hash *p_hash_syms) { + Scope *p_scope = malloc(sizeof(Scope)); + + p_scope->p_hash_global = p_hash_syms; + p_scope->p_stack_scopes = stack_new(); + + return (p_scope); +} + +void +scope_delete(Scope *p_scope) { + while (!stack_empty(p_scope->p_stack_scopes)) + scope_down(p_scope); + + stack_delete(p_scope->p_stack_scopes); + + free(p_scope); +} + +void +scope_up(Scope *p_scope) { + stack_push(p_scope->p_stack_scopes, hash_new(1024)); +} + +void +scope_down(Scope *p_scope) { + Hash *p_hash_syms = stack_pop(p_scope->p_stack_scopes); + hash_iterate(p_hash_syms, symbol_cleanup_hash_syms_cb); + hash_delete(p_hash_syms); +} + +static Hash* +_scope_get_hash(Scope *p_scope, char *c_key) { + StackIterator *p_iter = stackiterator_new(p_scope->p_stack_scopes); + + while (stackiterator_has_next(p_iter)) { + Hash *p_hash_syms = stackiterator_next(p_iter); + Symbol *p_symbol = hash_get(p_hash_syms, c_key); + + if (p_symbol != NULL) { + stackiterator_delete(p_iter); + return (p_hash_syms); + } + } + + stackiterator_delete(p_iter); + + if (hash_get(p_scope->p_hash_global, c_key)) + return (p_scope->p_hash_global); + + return (NULL); +} + +Symbol* +scope_get(Scope *p_scope, char *c_key) { + Hash *p_hash_syms = _scope_get_hash(p_scope, c_key); + + if (p_hash_syms == NULL) + return (NULL); + + return (hash_get(p_hash_syms, c_key)); +} + +Symbol* +scope_remove(Scope *p_scope, char *c_key) { + Hash *p_hash_syms = _scope_get_hash(p_scope, c_key); + + if (p_hash_syms == NULL) + return (NULL); + + Symbol *p_symbol = hash_remove(p_hash_syms, c_key); + + return (p_symbol); +} + +_Bool +scope_exists(Scope *p_scope, char *c_key) { + return (scope_get(p_scope, c_key) != NULL); +} + +_Bool +scope_reset(Scope *p_scope, char *c_key, Symbol *p_symbol) { + Hash *p_hash_syms = _scope_get_hash(p_scope, c_key); + + if (p_hash_syms == NULL) + return (false); + + hash_remove(p_hash_syms, c_key); + hash_insert(p_hash_syms, c_key, p_symbol); + + return (true); +} + +_Bool +scope_newset(Scope *p_scope, char *c_key, Symbol *p_symbol) { + Hash *p_hash_syms = NULL; + + if (stack_empty(p_scope->p_stack_scopes)) { + if (hash_get(p_scope->p_hash_global, c_key) != NULL) + return (false); + + p_hash_syms = p_scope->p_hash_global; + + } else { + p_hash_syms = stack_top(p_scope->p_stack_scopes); + } + + hash_insert(p_hash_syms, c_key, p_symbol); + + return (true); +} -- cgit v1.2.3