#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 */