diff options
author | tomsmeding <tom.smeding@gmail.com> | 2016-11-20 11:27:07 +0100 |
---|---|---|
committer | tomsmeding <tom.smeding@gmail.com> | 2016-11-20 11:27:07 +0100 |
commit | 3b390967e7c2ee4ac6d1a67c77f40ed43005e012 (patch) | |
tree | 4be72c3ed32277329c472c1dc72793577ea29195 /prelude.cpp |
Initial
Diffstat (limited to 'prelude.cpp')
-rw-r--r-- | prelude.cpp | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/prelude.cpp b/prelude.cpp new file mode 100644 index 0000000..eb503b0 --- /dev/null +++ b/prelude.cpp @@ -0,0 +1,68 @@ +#include <iostream> +#include <sstream> +#include <string> +#include "error.h" +#include "prelude.h" + +using namespace std; + + +Environment prelude; + +const AST afterBootstrap=AST(R"RAW( +(do + (def '. \f \g \x (f (g x))) + (def 'flip \f \a \b (f b a)) + (def 'id \x x) + (def 'const \x \y x) + (def 'print (. putstr repr))) +)RAW"); + +class PreludeInit{ +public: + PreludeInit(Environment &intoEnv){ + intoEnv.define("repr",AST::makeNative([](const AST &ast) -> AST { + stringstream ss; + ss<<ast; + String res=ss.str(); + return AST::makeString(res); + })); + + intoEnv.define("putstr",AST::makeNative([](const AST &ast) -> AST { + if(ast.type!=AST::Type::string){ + throw TypeError("Argument to 'putstr' is not a String"); + } + cout<<ast.strval<<endl; + return AST(); + })); + + intoEnv.define("def",[](Environment &env,const AST &arg1) -> AST { + return AST::makeNative([&env,arg1](const AST &arg2) -> AST { + if(arg1.type!=AST::Type::name){ + throw TypeError("First argument to 'def' is not a Name"); + } + env.define(arg1.nameval,arg2); + return AST(); + }); + }); + + intoEnv.define("do",AST::makeNative([](const AST&) -> AST { + throw logic_error("'do' stub called; this should not happen"); + })); + + intoEnv.define2("+",[](Environment&,const AST &arg1,const AST &arg2) -> AST { + if(arg1.type!=arg2.type){ + throw TypeError("Unequal types in '+'"); + } + if(arg1.type==AST::Type::number){ + return AST::makeNumber(arg1.numval+arg2.numval); + } else if(arg1.type==AST::Type::string){ + return AST::makeString(arg1.strval+arg2.strval); + } else { + throw TypeError("Arguments to '+' neither Number nor String"); + } + }); + + intoEnv.run(afterBootstrap); + } +} preludeInit(prelude); |