diff options
author | dos-reis <gdr@axiomatics.org> | 2014-11-18 02:14:12 +0000 |
---|---|---|
committer | dos-reis <gdr@axiomatics.org> | 2014-11-18 02:14:12 +0000 |
commit | 8c3ecc5bfb24190fee0244a6826bbddf136f9484 (patch) | |
tree | 76f4eb23c6badd1ff952f41c2cf6f5ae633df025 | |
parent | 9e1699c14362f6c8f63354a93125ec8b1f6f1e9c (diff) | |
download | open-axiom-8c3ecc5bfb24190fee0244a6826bbddf136f9484.tar.gz |
Add visitor to Dynamic values.
-rw-r--r-- | src/ChangeLog | 4 | ||||
-rw-r--r-- | src/include/sexpr.H | 1 | ||||
-rw-r--r-- | src/include/vm.H | 38 | ||||
-rw-r--r-- | src/rt/Lisp.cc | 172 | ||||
-rw-r--r-- | src/rt/Makefile.am | 14 | ||||
-rw-r--r-- | src/rt/Makefile.in | 108 | ||||
-rw-r--r-- | src/rt/driver.cc | 78 | ||||
-rw-r--r-- | src/rt/vm.cc | 33 | ||||
-rw-r--r-- | src/utils/Makefile.am | 5 | ||||
-rw-r--r-- | src/utils/Makefile.in | 30 |
10 files changed, 360 insertions, 123 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index a8a46f96..4745403d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2014-11-17 Gabriel Dos Reis <gdr@integrable-solutions.net> + + * boot/bemol.cc: New. + 2014-11-16 Gabriel Dos Reis <gdr@integrable-solutions.net> * syntax/Makefile.in: Remove. diff --git a/src/include/sexpr.H b/src/include/sexpr.H index 82dba2a3..6920e436 100644 --- a/src/include/sexpr.H +++ b/src/include/sexpr.H @@ -280,6 +280,7 @@ namespace OpenAxiom { using base::rend; using base::size; using base::empty; + using base::front; ListSyntax(); ListSyntax(const base&, bool); diff --git a/src/include/vm.H b/src/include/vm.H index 2c1eafde..3ee093ea 100644 --- a/src/include/vm.H +++ b/src/include/vm.H @@ -217,10 +217,16 @@ namespace OpenAxiom { // ------------- // Any internal value is of a class derived from this. internal_type Dynamic { + struct Visitor; virtual ~Dynamic(); - virtual void format_on(std::ostream&) const = 0; + virtual void accept(Visitor&) const = 0; }; + // Provide an S-view of a T-typed expression, assuming the type T + // derives from S. + template<typename S, typename T> + inline const S& as(const T& t) { return t; } + template<> struct ValueTrait<Dynamic> { enum Tag : ValueBits { tag = 0x6 }; @@ -420,7 +426,7 @@ namespace OpenAxiom { Package* package; SymbolAttribute attributes; explicit Symbol(InternedString); - void format_on(std::ostream&) const override; + void accept(Visitor&) const override; bool has(SymbolAttribute x) const { return (attributes & x) == x; } }; @@ -456,6 +462,14 @@ namespace OpenAxiom { sym->function = fun; return fun; } + + // -- Argument binding as value. + // Binding a parameter to a value in a call. + struct Binding : Dynamic { + Symbol* symbol; + Value value; + void accept(Visitor&) const override; + }; // -- Environments. struct Environment { @@ -482,7 +496,8 @@ namespace OpenAxiom { std::set<Symbol, CmpByName> symbols; explicit Package(InternedString); - void format_on(std::ostream&) const override; + void accept(Visitor&) const override; + void format_on(std::ostream&) const; Symbol* make_symbol(InternedString); Symbol* find_symbol(InternedString); }; @@ -495,7 +510,7 @@ namespace OpenAxiom { Value type; FunctionBase(const Symbol* n, Value t = Value::nil) : name(n), type(t) { } - void format_on(std::ostream&) const override; + void accept(Visitor&) const override; }; // ------------------------ @@ -517,6 +532,7 @@ namespace OpenAxiom { BuiltinFunction(const Symbol* n, Code c) : FunctionBase(n), code(c) { } + void accept(Visitor&) const override; }; using NullaryOperator = BuiltinFunction<NullaryCode>; @@ -541,6 +557,20 @@ namespace OpenAxiom { } }; + // -- Dynamic::Visitor -- + struct Dynamic::Visitor { + virtual void visit(const Symbol&) = 0; + virtual void visit(const Binding&) = 0; + virtual void visit(const Package&) = 0; + virtual void visit(const FunctionBase&) = 0; + virtual void visit(const NullaryOperator&); + virtual void visit(const UnaryOperator&); + virtual void visit(const BinaryOperator&); + }; + + template<typename Code> + void BuiltinFunction<Code>::accept(Visitor& v) const { v.visit(*this); } + // ------------------ // -- BasicContext -- // ------------------ 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) { diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am index 74b0e6f7..8c0bec65 100644 --- a/src/utils/Makefile.am +++ b/src/utils/Makefile.am @@ -41,7 +41,10 @@ libOpenAxiom_a_SOURCES = \ ../io/Input.cc \ ../io/std-streams.cc \ ../syntax/token.cc \ - ../syntax/sexpr.cc + ../syntax/sexpr.cc \ + ../rt/vm.cc \ + ../rt/Lisp.cc \ + ../rt/Database.cc oa_public_headers = hash-table string-pool diff --git a/src/utils/Makefile.in b/src/utils/Makefile.in index 02d718b3..4600bb81 100644 --- a/src/utils/Makefile.in +++ b/src/utils/Makefile.in @@ -140,7 +140,8 @@ am__dirstamp = $(am__leading_dot)dirstamp am_libOpenAxiom_a_OBJECTS = storage.$(OBJEXT) string-pool.$(OBJEXT) \ command.$(OBJEXT) filesystem.$(OBJEXT) ../io/Input.$(OBJEXT) \ ../io/std-streams.$(OBJEXT) ../syntax/token.$(OBJEXT) \ - ../syntax/sexpr.$(OBJEXT) + ../syntax/sexpr.$(OBJEXT) ../rt/vm.$(OBJEXT) \ + ../rt/Lisp.$(OBJEXT) ../rt/Database.$(OBJEXT) libOpenAxiom_a_OBJECTS = $(am_libOpenAxiom_a_OBJECTS) PROGRAMS = $(noinst_PROGRAMS) am_hammer_OBJECTS = hammer.$(OBJEXT) @@ -412,7 +413,10 @@ libOpenAxiom_a_SOURCES = \ ../io/Input.cc \ ../io/std-streams.cc \ ../syntax/token.cc \ - ../syntax/sexpr.cc + ../syntax/sexpr.cc \ + ../rt/vm.cc \ + ../rt/Lisp.cc \ + ../rt/Database.cc oa_public_headers = hash-table string-pool oa_target_headerdir = $(oa_target_includedir)/open-axiom @@ -481,6 +485,18 @@ clean-noinstLIBRARIES: ../syntax/$(DEPDIR)/$(am__dirstamp) ../syntax/sexpr.$(OBJEXT): ../syntax/$(am__dirstamp) \ ../syntax/$(DEPDIR)/$(am__dirstamp) +../rt/$(am__dirstamp): + @$(MKDIR_P) ../rt + @: > ../rt/$(am__dirstamp) +../rt/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) ../rt/$(DEPDIR) + @: > ../rt/$(DEPDIR)/$(am__dirstamp) +../rt/vm.$(OBJEXT): ../rt/$(am__dirstamp) \ + ../rt/$(DEPDIR)/$(am__dirstamp) +../rt/Lisp.$(OBJEXT): ../rt/$(am__dirstamp) \ + ../rt/$(DEPDIR)/$(am__dirstamp) +../rt/Database.$(OBJEXT): ../rt/$(am__dirstamp) \ + ../rt/$(DEPDIR)/$(am__dirstamp) libOpenAxiom.a: $(libOpenAxiom_a_OBJECTS) $(libOpenAxiom_a_DEPENDENCIES) $(EXTRA_libOpenAxiom_a_DEPENDENCIES) $(AM_V_at)-rm -f libOpenAxiom.a @@ -503,6 +519,7 @@ hammer$(EXEEXT): $(hammer_OBJECTS) $(hammer_DEPENDENCIES) $(EXTRA_hammer_DEPENDE mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f ../io/*.$(OBJEXT) + -rm -f ../rt/*.$(OBJEXT) -rm -f ../syntax/*.$(OBJEXT) distclean-compile: @@ -510,6 +527,9 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@../io/$(DEPDIR)/Input.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../io/$(DEPDIR)/std-streams.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@../rt/$(DEPDIR)/Database.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@../rt/$(DEPDIR)/Lisp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@../rt/$(DEPDIR)/vm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../syntax/$(DEPDIR)/sexpr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../syntax/$(DEPDIR)/token.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/command.Po@am__quote@ @@ -662,6 +682,8 @@ distclean-generic: -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f ../io/$(DEPDIR)/$(am__dirstamp) -rm -f ../io/$(am__dirstamp) + -rm -f ../rt/$(DEPDIR)/$(am__dirstamp) + -rm -f ../rt/$(am__dirstamp) -rm -f ../syntax/$(DEPDIR)/$(am__dirstamp) -rm -f ../syntax/$(am__dirstamp) @@ -674,7 +696,7 @@ clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am - -rm -rf ../io/$(DEPDIR) ../syntax/$(DEPDIR) ./$(DEPDIR) + -rm -rf ../io/$(DEPDIR) ../rt/$(DEPDIR) ../syntax/$(DEPDIR) ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -720,7 +742,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ../io/$(DEPDIR) ../syntax/$(DEPDIR) ./$(DEPDIR) + -rm -rf ../io/$(DEPDIR) ../rt/$(DEPDIR) ../syntax/$(DEPDIR) ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic |