Commit dc7d5135 authored by Chris Müller's avatar Chris Müller
Browse files

implement symbol environments with red-black trees

parent 3ad01f40
/*
* Cherry programming language
* Copyright (C) 2013 Christoph Mueller
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "cherry/runtime.h"
......@@ -88,8 +88,6 @@ struct org_cherry_value* org_cherry_float(cy_float_t float_value);
struct org_cherry_value* org_cherry_string(cy_byte_t* string_value);
struct org_cherry_value* org_cherry_char(cy_unicode_t char_value);
struct org_cherry_pair {
struct org_cherry_meta meta;
......@@ -117,10 +115,16 @@ struct org_cherry_symbollist;
struct org_cherry_symbollist* org_cherry_symbollist(void);
struct org_cherry_value* org_cherry_symbollist_get(struct org_cherry_symbollist* table, cy_byte_t* name);
struct org_cherry_symbollist* org_cherry_env_push(struct org_cherry_symbollist* env);
struct org_cherry_symbollist* org_cherry_env_pop(struct org_cherry_symbollist* env);
struct org_cherry_value* org_cherry_env_lookup(struct org_cherry_symbollist* env, struct org_cherry_value* symbol);
int org_cherry_env_add(struct org_cherry_symbollist* env, struct org_cherry_value* symbol, struct org_cherry_value* value);
extern struct org_cherry_symbollist* org_cherry_global_symbollist;
extern struct org_cherry_value* org_cherry_symbol_emptylist;
extern struct org_cherry_value* org_cherry_symbol_true;
extern struct org_cherry_value* org_cherry_symbol_false;
extern struct org_cherry_value* org_cherry_true;
extern struct org_cherry_value* org_cherry_false;
extern struct org_cherry_value* org_cherry_symbol_quote;
extern struct org_cherry_value* org_cherry_symbol_define;
extern struct org_cherry_value* org_cherry_symbol_lambda;
......
set(CORE_SOURCES
lexer.c
read.c
value.c
tables.c)
......
......@@ -326,4 +326,78 @@ org_cherry_symbollist_get(struct org_cherry_symbollist* tree, cy_byte_t* name)
}
struct org_cherry_symbollist*
org_cherry_env_push(struct org_cherry_symbollist* env)
{
assert(env != 0);
struct org_cherry_symbollist* frame = org_cherry_symbollist();
frame->parent = env;
return frame;
}
struct org_cherry_symbollist*
org_cherry_env_pop(struct org_cherry_symbollist* env)
{
assert(env != 0);
struct org_cherry_symbollist* frame = env->parent;
env->parent = 0;
return frame;
}
struct org_cherry_value*
org_cherry_env_lookup(struct org_cherry_symbollist* env, struct org_cherry_value* symbol)
{
while(env != 0) {
struct RbNode* node = env->root;
while(node != 0) {
if(symbol < node->symbol)
node = node->left;
else if(symbol > node->symbol)
node = node->right;
else
return node->value;
}
env = env->parent;
}
return 0;
}
int
org_cherry_env_add(struct org_cherry_symbollist* env, struct org_cherry_value* symbol, struct org_cherry_value* value)
{
assert(env != 0);
assert(symbol != 0);
if(env->root == 0) {
env->root = rbnode(BLACK, 0, symbol, value);
return TRUE;
}
struct RbNode* node = env->root;
struct RbNode* current_node = 0;
while(current_node == 0) {
if(symbol < node->symbol) {
if(node->left == 0)
current_node = node->left = rbnode(RED, node, symbol, value);
else
node = node->left;
} else if(symbol > node->symbol) {
if(node->right == 0)
current_node = node->right = rbnode(RED, node, symbol, value);
else
node = node->right;
} else
return FALSE;
}
rbnode_remedy_double_red(env, current_node);
return TRUE;
}
......@@ -26,8 +26,8 @@
struct org_cherry_symbollist* org_cherry_global_symbollist;
struct org_cherry_value* org_cherry_symbol_emptylist;
struct org_cherry_value* org_cherry_symbol_true;
struct org_cherry_value* org_cherry_symbol_false;
struct org_cherry_value* org_cherry_true;
struct org_cherry_value* org_cherry_false;
struct org_cherry_value* org_cherry_symbol_define;
struct org_cherry_value* org_cherry_symbol_lambda;
......@@ -159,18 +159,18 @@ org_cherry_initialize(struct org_cherry_pair* arguments)
GC_INIT();
org_cherry_global_symbollist = org_cherry_symbollist();
org_cherry_symbol_true = org_cherry_value_alloc();
org_cherry_symbol_true->meta.type = CY_BOOLEAN;
org_cherry_symbol_true->boolean_value = 1;
org_cherry_true = org_cherry_value_alloc();
org_cherry_true->meta.type = CY_BOOLEAN;
org_cherry_true->boolean_value = 1;
org_cherry_symbol_false = org_cherry_value_alloc();
org_cherry_symbol_false->meta.type = CY_BOOLEAN;
org_cherry_symbol_false->boolean_value = 0;
org_cherry_false = org_cherry_value_alloc();
org_cherry_false->meta.type = CY_BOOLEAN;
org_cherry_false->boolean_value = 0;
org_cherry_symbol_emptylist = org_cherry_value_alloc();
org_cherry_symbol_emptylist->meta.type = CY_EMPTYLIST;
org_cherry_symbol_define = org_cherry_symbol("quote");
org_cherry_symbol_quote = org_cherry_symbol("quote");
org_cherry_symbol_define = org_cherry_symbol("define");
org_cherry_symbol_lambda = org_cherry_symbol("lambda");
org_cherry_symbol_if = org_cherry_symbol("if");
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment