diff options
| author | Paul Buetow <paul@buetow.org> | 2009-10-30 14:54:34 +0000 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2009-10-30 14:54:34 +0000 |
| commit | 1542ff3a3927916c23dabffff9533b58f63f4b54 (patch) | |
| tree | 4a34357fc9723d4f65daa3b5a5de4099bcfd7424 /src/core/scope.c | |
| parent | 9eb12638e152d981492382cb534edb89a8625990 (diff) | |
| parent | 1bc73e78278b630768723869d277d05404feae03 (diff) | |
Diffstat (limited to 'src/core/scope.c')
| -rw-r--r-- | src/core/scope.c | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/src/core/scope.c b/src/core/scope.c new file mode 100644 index 0000000..acbec1f --- /dev/null +++ b/src/core/scope.c @@ -0,0 +1,169 @@ +/*:* + *: File: ./src/core/scope.c + *: A simple interpreter + *: + *: WWW : http://fype.buetow.org + *: AUTHOR : http://paul.buetow.org + *: E-Mail : fype at dev.buetow.org + *: + *: Copyright (c) 2005 - 2008, Paul Buetow + *: 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 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 "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); +} + +void +_scope_print_cb(void *p_void, int i_level) { + Hash *p_hash_syms = p_void; + if (i_level > 0) + printf("%d level(s) up:\n", i_level); + hash_iterate_key(p_hash_syms, symbol_print_cb); +} + +void +scope_print(Scope *p_scope) { + printf("Scopes:\n"); + printf("Scope stack size: %d\n", stack_size(p_scope->p_stack_scopes)); + printf("Global symbols:\n"); + hash_iterate_key(p_scope->p_hash_global, symbol_print_cb); + printf("Local symbols:\n"); + stack_iterate_level(p_scope->p_stack_scopes, _scope_print_cb); +} |
