#ifndef __I_VALUES_H #define __I_VALUES_H /* 5D programming language Copyright (C) 2011 Danny Milosavljevic 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 . */ #include #include #include <5D/Allocators> #include <5D/Values> namespace Values { struct Cons : Node { NodeT tail; /* Cons or Application or something else. */ NodeT head; // FIXME virtual std::string str(void) const; }; struct Application : Node { NodeT operator_; NodeT operand; NodeT result; int resultGeneration; //virtual std::string str(void) const; }; struct Abstraction : Node { NodeT parameter; NodeT body; //virtual std::string str(void) const; }; struct Str : Box { bool bAtomicity; size_t size; explicit Str(void* value) : Box(value, NULL) { bAtomicity = false; } //virtual std::string str(void) const; }; #if 0 struct Vector : Node { int count; NodeT elements[1]; /* stored in-line here */ explicit Vector(int count, NodeT* elements) { this->count = count; for(int i = 0; i < count; ++i) this->elements[i] = elements[i]; } /* slow when vector content is inline! Vector slice(int beginning, int end) { if(beginning < 0) beginning = 0; int count = end - beginning; if(count < 0) count = 0; if(count > this->count - beginning) count = this->count - beginning; return Vector(count, elements + beginning); }*/ }; #endif NodeT makeStrSlice(Str* s, int offset); /* Str */ bool str_P(NodeT node); static inline char* get_str_buffer(NodeT node) { return (char*) (((Str*) node)->value); } static inline size_t get_str_size(NodeT node) { return(((Str*) node)->size); } static inline bool get_str_atomic(NodeT node) { return(((Str*) node)->bAtomicity); } static inline bool abstraction_P(NodeT root) { return(dynamic_cast(root) != NULL); } static inline bool application_P(NodeT root) { return(dynamic_cast(root) != NULL); } static inline NodeT get_application_operator(NodeT app) { return(((Application*)app)->operator_); } static inline NodeT get_application_operand(NodeT app) { return(((Application*)app)->operand); } static inline NodeT get_abstraction_body(NodeT abstraction) { return(((Abstraction*)abstraction)->body); } static inline NodeT get_abstraction_parameter(NodeT abstraction) { return(((Abstraction*)abstraction)->parameter); } static inline NodeT get_cons_head(NodeT cons) { return(((Cons*) cons)->head); } static inline NodeT get_cons_tail(NodeT cons) { return(((Cons*) cons)->tail); } static inline NodeT get_pair_fst(NodeT p) { return(get_cons_head(p)); } static inline NodeT get_pair_snd(NodeT p) { return(get_cons_head(get_cons_tail(p))); } NodeT makeApplication(NodeT fn, NodeT argument); NodeT makeAbstraction(NodeT parameter, NodeT body); NodeT makeOperation(NodeT operator_, NodeT operand_1, NodeT operand_2); static inline bool pair_P(NodeT node) { return(dynamic_cast(node) != NULL); } static inline bool nil_P(NodeT node) { return(node == NULL); } static inline NodeT uncacheNodeResult(void* userData, NodeT node) { if(application_P(node)) { Application* app = dynamic_cast(node); app->resultGeneration = 0; /* make sure it is not used */ return(app); } else return(node); } NodeT makeCons(NodeT a, NodeT b); NodeT makePair(NodeT a, NodeT b); void set_cons_tail(NodeT cons, NodeT value); void set_box_value(NodeT box, void* value); }; /* namespace Values */ #include "Values/Symbol" #include "Values/Keyword" #include "Values/Hashtable" #endif /* __I_VALUES_H */