aboutsummaryrefslogtreecommitdiff
path: root/src/rt
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2014-11-18 02:14:12 +0000
committerdos-reis <gdr@axiomatics.org>2014-11-18 02:14:12 +0000
commit8c3ecc5bfb24190fee0244a6826bbddf136f9484 (patch)
tree76f4eb23c6badd1ff952f41c2cf6f5ae633df025 /src/rt
parent9e1699c14362f6c8f63354a93125ec8b1f6f1e9c (diff)
downloadopen-axiom-8c3ecc5bfb24190fee0244a6826bbddf136f9484.tar.gz
Add visitor to Dynamic values.
Diffstat (limited to 'src/rt')
-rw-r--r--src/rt/Lisp.cc172
-rw-r--r--src/rt/Makefile.am14
-rw-r--r--src/rt/Makefile.in108
-rw-r--r--src/rt/driver.cc78
-rw-r--r--src/rt/vm.cc33
5 files changed, 291 insertions, 114 deletions
diff --git a/src/rt/Lisp.cc b/src/rt/Lisp.cc
index d36f059c..71b3c2b1 100644
--- a/src/rt/Lisp.cc
+++ b/src/rt/Lisp.cc
@@ -280,15 +280,54 @@ namespace OpenAxiom {
}
// Return the denotation of a sharp-apostrophe syntax.
+
+ static const Callable*
+ symbol_function(Evaluator* ctx, const Sexpr::SymbolSyntax& s) {
+ auto sym = retrieve_symbol(ctx, s);
+ if (sym->function == nullptr)
+ unbound_function_symbol_error(sym);
+ return sym->function;
+ }
+
static Value
evaluate(Evaluator* ctx, const Sexpr::Function& x) {
auto s = dynamic_cast<const Sexpr::SymbolSyntax*>(x.body());
if (s == nullptr)
throw Unimplemented("FUNCTION of non-symbol expression");
- auto sym = retrieve_symbol(ctx, *s);
- if (sym->function == nullptr)
- unbound_function_symbol_error(sym);
- return to_value(sym->function);
+ return to_value(symbol_function(ctx, *s));
+ }
+
+ static Value
+ evaluate(Evaluator* ctx, const Sexpr::QuoteSyntax& x) {
+ return ctx->make_value(x.body());
+ }
+
+ // -- special operators
+ using SpecialOperator = Value (*)(Evaluator*, const Sexpr::Syntax&);
+ const NamedConstant<SpecialOperator> special_ops[] = {
+ };
+
+ static SpecialOperator
+ special_operator(const Sexpr::SymbolSyntax& s) {
+ auto name = canonical_name(s);
+ for (auto& x : special_ops) {
+ if (x.name == name)
+ return x.value;
+ }
+ return nullptr;
+ }
+
+ static Value
+ evaluate(Evaluator* ctx, const Sexpr::ListSyntax& x) {
+ if (x.empty())
+ return Value::nil;
+ auto s = dynamic_cast<const Sexpr::SymbolSyntax*>(x.front());
+ if (s == nullptr)
+ // FIXME: real error
+ unimplemented(x);
+ if (auto op = special_operator(*s))
+ return op(ctx, x);
+ auto fun = symbol_function(ctx, *s);
}
Value
@@ -304,7 +343,7 @@ namespace OpenAxiom {
void visit(const SymbolSyntax& x) { result = evaluate(ctx, x); }
void visit(const ReferenceSyntax& x) { unimplemented(x); }
void visit(const AnchorSyntax& x) { unimplemented(x); }
- void visit(const QuoteSyntax& x) { unimplemented(x); }
+ void visit(const QuoteSyntax& x) { result = evaluate(ctx, x); }
void visit(const AntiquoteSyntax& x) { unimplemented(x); }
void visit(const Expand& x) { unimplemented(x); }
void visit(const Eval& x) { unimplemented(x); }
@@ -312,7 +351,7 @@ namespace OpenAxiom {
void visit(const Function& x) { result = evaluate(ctx, x); }
void visit(const Include& x) { unimplemented(x); }
void visit(const Exclude& x) { unimplemented(x); }
- void visit(const ListSyntax& x) { unimplemented(x); }
+ void visit(const ListSyntax& x) { result = evaluate(ctx, x); }
void visit(const VectorSyntax& x) { unimplemented(x); }
};
@@ -323,6 +362,15 @@ namespace OpenAxiom {
return v.result;
}
+ Value*
+ Evaluator::lexical_binding(String name) {
+ if (env_stack.empty())
+ return nullptr;
+ else if (auto b = env_stack.back().lookup(name))
+ return &b->value;
+ return nullptr;
+ }
+
Value
Evaluator::toplevel_form(const Sexpr::Syntax* x) {
auto anchors = std::move(anchor_map);
@@ -332,11 +380,64 @@ namespace OpenAxiom {
return v;
}
+ template<typename... Ts>
+ using Operation = Value (*)(Ts...);
+
+ template<Operation<Value> fun>
+ RuntimeOperation<Value> runtime() {
+ return [](BasicContext*, Value x) { return fun(x); };
+ }
+
+ const NamedConstant<UnaryCode> unary_builtins[] = {
+ { "CONSP", runtime<consp>() },
+ { "ATOM", runtime<atom>() },
+ { "SYMBOLP", runtime<symbolp>() },
+ { "KEYWORDP", runtime<keywordp>() },
+ };
+
+ template<typename T>
+ static void
+ define_builtin_operator(Evaluator* ctx, const char* s, T t) {
+ auto name = ctx->intern(s);
+ auto sym = ctx->current_package()->make_symbol(name);
+ sym->function = ctx->make_operator(sym, t);
+ }
+
+ static void
+ define_builtin_operators(Evaluator* ctx) {
+ for (auto& x : unary_builtins)
+ define_builtin_operator(ctx, x.name, x.value);
+ }
+
+ static Symbol*
+ make_special_symbol(Evaluator* ctx, const char* s) {
+ auto name = ctx->intern(s);
+ auto sym = ctx->current_package()->make_symbol(name);
+ sym->attributes = SymbolAttribute::Special;
+ return sym;
+ }
+
+ static Symbol*
+ define_features(Evaluator* ctx) {
+ auto sym = make_special_symbol(ctx, "*FEATURES*");
+ sym->value = Value::nil;
+ return sym;
+ }
+
+ static void
+ define_current_package(Evaluator* ctx) {
+ auto sym = make_special_symbol(ctx, "*PACKAGE*");
+ sym->value = to_value(ctx->current_package());
+ }
+
Evaluator::Evaluator()
: core(make_package(intern("AxiomCore"))),
- ns(core)
+ ns(core),
+ feature_list(define_features(this))
{
define_special_constants(this);
+ define_builtin_operators(this);
+ define_current_package(this);
env_stack.push_back(Environment{ });
}
@@ -377,27 +478,58 @@ namespace OpenAxiom {
os << '"';
}
- static void format(const Symbol* s, std::ostream& os) {
- // FIXME: Handle escapes.
- auto n = s->name;
- std::copy(n->begin(), n->end(), std::ostream_iterator<char>(os));
- }
-
+ static void format(const Dynamic*, std::ostream&);
+
void format(Value v, std::ostream& os) {
if (v == Value::nil)
os << "NIL";
+ else if (v == Value::t)
+ os << "T";
else if (is<Fixnum>(v))
os << FixnumBits(to_fixnum(v));
- else if (auto p = to_pair_if_can(v))
- format(p, os);
- else if (auto s = to_string_if_can(v))
- format(s, os);
- else if (auto s = to_symbol_if_can(v))
- format(s, os);
+ else if (is<Pair>(v))
+ format(to_pair(v), os);
+ else if (is<String>(v))
+ format(to_string(v), os);
+ else if (is<Dynamic>(v))
+ format(to_dynamic(v), os);
else
- os << "<unprintable>";
+ os << "#<unprintable>";
}
+ static void format(const Dynamic* x, std::ostream& os) {
+ struct V : Dynamic::Visitor {
+ std::ostream& os;
+ V(std::ostream& s) : os(s) { }
+ void visit(const Symbol& s) {
+ // FIXME: handle escapes.
+ std::copy(s.name->begin(), s.name->end(),
+ std::ostream_iterator<char>(os));
+ }
+ void visit(const Package& p) {
+ os << "#<PACKAGE ";
+ std::copy(p.name->begin(), p.name->end(),
+ std::ostream_iterator<char>(os));
+ os << '>';
+ }
+ void visit(const FunctionBase& f) {
+ os << "#<FUNCTION ";
+ visit(*f.name);
+ os << '>';
+ }
+ void visit(const Binding& b) {
+ os << '(';
+ visit(*b.symbol);
+ os << ' ';
+ format(b.value, os);
+ os << ')';
+ }
+ };
+
+ V v { os };
+ x->accept(v);
+ }
+
// -- assoc: (T, List Pair(T, S)) -> S
Value assoc(Value key, Pair al) {
while (al != nullptr) {
diff --git a/src/rt/Makefile.am b/src/rt/Makefile.am
index 7887d6e3..8c3fdc14 100644
--- a/src/rt/Makefile.am
+++ b/src/rt/Makefile.am
@@ -30,14 +30,14 @@
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
-noinst_LIBRARIES = libruntime.a
-
-libruntime_a_SOURCES = vm.cc Lisp.cc Database.cc
-
-oa_target_incdir = $(top_builddir)/$(target)/include
-
-libruntime_a_CPPFLAGS = -I$(top_srcdir)/src/include -I$(oa_target_incdir)
+noinst_PROGRAMS = lisp
+lisp_SOURCES = driver.cc
+lisp_LDADD = $(oa_target_libdir)/libOpenAxiom.a
+AM_CXXFLAGS = \
+ -I$(top_srcdir)/src/include \
+ -I$(oa_target_includedir) \
+ -I$(top_builddir)/config
.PHONY: all-rt
all-rt: all-am
diff --git a/src/rt/Makefile.in b/src/rt/Makefile.in
index 16d97ddc..a2ac05a3 100644
--- a/src/rt/Makefile.in
+++ b/src/rt/Makefile.in
@@ -111,6 +111,7 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
+noinst_PROGRAMS = lisp$(EXEEXT)
subdir = src/rt
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/config/mkinstalldirs \
@@ -128,17 +129,14 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config/openaxiom-c-macros.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
-LIBRARIES = $(noinst_LIBRARIES)
-ARFLAGS = cru
-AM_V_AR = $(am__v_AR_@AM_V@)
-am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@)
-am__v_AR_0 = @echo " AR " $@;
-am__v_AR_1 =
-libruntime_a_AR = $(AR) $(ARFLAGS)
-libruntime_a_LIBADD =
-am_libruntime_a_OBJECTS = libruntime_a-vm.$(OBJEXT) \
- libruntime_a-Lisp.$(OBJEXT) libruntime_a-Database.$(OBJEXT)
-libruntime_a_OBJECTS = $(am_libruntime_a_OBJECTS)
+PROGRAMS = $(noinst_PROGRAMS)
+am_lisp_OBJECTS = driver.$(OBJEXT)
+lisp_OBJECTS = $(am_lisp_OBJECTS)
+lisp_DEPENDENCIES = $(oa_target_libdir)/libOpenAxiom.a
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
@@ -155,10 +153,6 @@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/config
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
-AM_V_lt = $(am__v_lt_@AM_V@)
-am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
-am__v_lt_0 = --silent
-am__v_lt_1 =
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
@@ -177,8 +171,8 @@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
-SOURCES = $(libruntime_a_SOURCES)
-DIST_SOURCES = $(libruntime_a_SOURCES)
+SOURCES = $(lisp_SOURCES)
+DIST_SOURCES = $(lisp_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -395,10 +389,13 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
void_type = @void_type@
-noinst_LIBRARIES = libruntime.a
-libruntime_a_SOURCES = vm.cc Lisp.cc Database.cc
-oa_target_incdir = $(top_builddir)/$(target)/include
-libruntime_a_CPPFLAGS = -I$(top_srcdir)/src/include -I$(oa_target_incdir)
+lisp_SOURCES = driver.cc
+lisp_LDADD = $(oa_target_libdir)/libOpenAxiom.a
+AM_CXXFLAGS = \
+ -I$(top_srcdir)/src/include \
+ -I$(oa_target_includedir) \
+ -I$(top_builddir)/config
+
all: all-am
.SUFFIXES:
@@ -434,13 +431,18 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
-clean-noinstLIBRARIES:
- -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
-libruntime.a: $(libruntime_a_OBJECTS) $(libruntime_a_DEPENDENCIES) $(EXTRA_libruntime_a_DEPENDENCIES)
- $(AM_V_at)-rm -f libruntime.a
- $(AM_V_AR)$(libruntime_a_AR) libruntime.a $(libruntime_a_OBJECTS) $(libruntime_a_LIBADD)
- $(AM_V_at)$(RANLIB) libruntime.a
+lisp$(EXEEXT): $(lisp_OBJECTS) $(lisp_DEPENDENCIES) $(EXTRA_lisp_DEPENDENCIES)
+ @rm -f lisp$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(lisp_OBJECTS) $(lisp_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -448,9 +450,7 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libruntime_a-Database.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libruntime_a-Lisp.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libruntime_a-vm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver.Po@am__quote@
.cc.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -476,48 +476,6 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
-libruntime_a-vm.o: vm.cc
-@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libruntime_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libruntime_a-vm.o -MD -MP -MF $(DEPDIR)/libruntime_a-vm.Tpo -c -o libruntime_a-vm.o `test -f 'vm.cc' || echo '$(srcdir)/'`vm.cc
-@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libruntime_a-vm.Tpo $(DEPDIR)/libruntime_a-vm.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='vm.cc' object='libruntime_a-vm.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libruntime_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libruntime_a-vm.o `test -f 'vm.cc' || echo '$(srcdir)/'`vm.cc
-
-libruntime_a-vm.obj: vm.cc
-@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libruntime_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libruntime_a-vm.obj -MD -MP -MF $(DEPDIR)/libruntime_a-vm.Tpo -c -o libruntime_a-vm.obj `if test -f 'vm.cc'; then $(CYGPATH_W) 'vm.cc'; else $(CYGPATH_W) '$(srcdir)/vm.cc'; fi`
-@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libruntime_a-vm.Tpo $(DEPDIR)/libruntime_a-vm.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='vm.cc' object='libruntime_a-vm.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libruntime_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libruntime_a-vm.obj `if test -f 'vm.cc'; then $(CYGPATH_W) 'vm.cc'; else $(CYGPATH_W) '$(srcdir)/vm.cc'; fi`
-
-libruntime_a-Lisp.o: Lisp.cc
-@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libruntime_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libruntime_a-Lisp.o -MD -MP -MF $(DEPDIR)/libruntime_a-Lisp.Tpo -c -o libruntime_a-Lisp.o `test -f 'Lisp.cc' || echo '$(srcdir)/'`Lisp.cc
-@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libruntime_a-Lisp.Tpo $(DEPDIR)/libruntime_a-Lisp.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Lisp.cc' object='libruntime_a-Lisp.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libruntime_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libruntime_a-Lisp.o `test -f 'Lisp.cc' || echo '$(srcdir)/'`Lisp.cc
-
-libruntime_a-Lisp.obj: Lisp.cc
-@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libruntime_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libruntime_a-Lisp.obj -MD -MP -MF $(DEPDIR)/libruntime_a-Lisp.Tpo -c -o libruntime_a-Lisp.obj `if test -f 'Lisp.cc'; then $(CYGPATH_W) 'Lisp.cc'; else $(CYGPATH_W) '$(srcdir)/Lisp.cc'; fi`
-@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libruntime_a-Lisp.Tpo $(DEPDIR)/libruntime_a-Lisp.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Lisp.cc' object='libruntime_a-Lisp.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libruntime_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libruntime_a-Lisp.obj `if test -f 'Lisp.cc'; then $(CYGPATH_W) 'Lisp.cc'; else $(CYGPATH_W) '$(srcdir)/Lisp.cc'; fi`
-
-libruntime_a-Database.o: Database.cc
-@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libruntime_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libruntime_a-Database.o -MD -MP -MF $(DEPDIR)/libruntime_a-Database.Tpo -c -o libruntime_a-Database.o `test -f 'Database.cc' || echo '$(srcdir)/'`Database.cc
-@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libruntime_a-Database.Tpo $(DEPDIR)/libruntime_a-Database.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Database.cc' object='libruntime_a-Database.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libruntime_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libruntime_a-Database.o `test -f 'Database.cc' || echo '$(srcdir)/'`Database.cc
-
-libruntime_a-Database.obj: Database.cc
-@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libruntime_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libruntime_a-Database.obj -MD -MP -MF $(DEPDIR)/libruntime_a-Database.Tpo -c -o libruntime_a-Database.obj `if test -f 'Database.cc'; then $(CYGPATH_W) 'Database.cc'; else $(CYGPATH_W) '$(srcdir)/Database.cc'; fi`
-@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libruntime_a-Database.Tpo $(DEPDIR)/libruntime_a-Database.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Database.cc' object='libruntime_a-Database.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libruntime_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libruntime_a-Database.obj `if test -f 'Database.cc'; then $(CYGPATH_W) 'Database.cc'; else $(CYGPATH_W) '$(srcdir)/Database.cc'; fi`
-
mostlyclean-libtool:
-rm -f *.lo
@@ -608,7 +566,7 @@ distdir: $(DISTFILES)
done
check-am: all-am
check: check-am
-all-am: Makefile $(LIBRARIES)
+all-am: Makefile $(PROGRAMS)
installdirs:
install: install-am
install-exec: install-exec-am
@@ -642,7 +600,7 @@ maintainer-clean-generic:
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
-clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
mostlyclean-am
distclean: distclean-am
@@ -714,7 +672,7 @@ uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
- clean-libtool clean-noinstLIBRARIES cscopelist-am ctags \
+ clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
diff --git a/src/rt/driver.cc b/src/rt/driver.cc
new file mode 100644
index 00000000..0b1efa72
--- /dev/null
+++ b/src/rt/driver.cc
@@ -0,0 +1,78 @@
+// Copyright (C) 2014, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, 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 OpenAxiom 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER
+// OR CONTRIBUTORS 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.
+
+// --% Author: Gabriel Dos Reis
+
+#include <open-axiom/Lisp>
+#include <iostream>
+#include <string>
+
+static OpenAxiom::Sexpr::RawInput
+raw_input(const std::string& line, OpenAxiom::Ordinal lineno) {
+ if (line.empty())
+ return { nullptr, nullptr, lineno };
+ auto p = reinterpret_cast<const OpenAxiom::Byte*>(&line[0]);
+ return { p, p + line.size(), lineno };
+}
+
+int main(int argc, char* argv[]) {
+ using namespace OpenAxiom;
+ Lisp::Evaluator lisp;
+
+ const char* prompt = "*> ";
+ std::string line;
+ Ordinal lineno { };
+ while (true) {
+ std::cout << prompt;
+ if (!std::getline(std::cin, line))
+ break;
+ else if (line.empty())
+ continue;
+ Sexpr::Reader reader { raw_input(line, ++lineno) };
+ while (true) {
+ try {
+ auto s = reader.read();
+ if (s == nullptr)
+ break;
+ auto value = lisp.eval(s);
+ Lisp::format(value, std::cout);
+ std::cout << '\n';
+ }
+ catch (const OpenAxiom::Diagnostics::BasicError& e) {
+ std::cerr << e.message() << std::endl;
+ }
+ }
+ }
+
+ std::cout << std::endl;
+}
+
diff --git a/src/rt/vm.cc b/src/rt/vm.cc
index 4cedc030..e85cb558 100644
--- a/src/rt/vm.cc
+++ b/src/rt/vm.cc
@@ -39,6 +39,20 @@
namespace OpenAxiom {
namespace VM {
+ void Dynamic::Visitor::visit(const NullaryOperator& x) {
+ visit(as<FunctionBase>(x));
+ }
+
+ void Dynamic::Visitor::visit(const UnaryOperator& x) {
+ visit(as<FunctionBase>(x));
+ }
+
+ void Dynamic::Visitor::visit(const BinaryOperator& x) {
+ visit(as<FunctionBase>(x));
+ }
+
+ void FunctionBase::accept(Visitor& v) const { v.visit(*this); }
+
// -- Environement
Environment::Environment() = default;
@@ -59,7 +73,7 @@ namespace OpenAxiom {
}
// -- Dynamic
- Dynamic::~Dynamic() { }
+ Dynamic::~Dynamic() = default;
// -- Symbol
Symbol::Symbol(InternedString s)
@@ -71,11 +85,10 @@ namespace OpenAxiom {
attributes()
{ }
- void Symbol::format_on(std::ostream& os) const {
- // FIXME: handle escapes.
- std::copy(name->begin(), name->end(),
- std::ostream_iterator<char>(os));
- }
+ void Symbol::accept(Visitor& v) const { v.visit(*this); }
+
+ // -- Binding
+ void Binding::accept(Visitor& v) const { v.visit(*this); }
// -- Package
Package::Package(InternedString s)
@@ -102,12 +115,7 @@ namespace OpenAxiom {
return p == symbols.end() ? nullptr : const_cast<Symbol*>(&*p);
}
- // -- FunctionBase
- void FunctionBase::format_on(std::ostream& os) const {
- os << "#<FUNCTION ";
- name->format_on(os);
- os << '>';
- }
+ void Package::accept(Visitor& v) const { v.visit(*this); }
Fixnum
count_nodes(Pair p) {
@@ -117,6 +125,7 @@ namespace OpenAxiom {
return Fixnum(n);
}
+
// -- BasicContext --
Package*
BasicContext::make_package(InternedString n) {