grand renaming to 'aqua' (well, 'Aqua' actually)
[aqualang.git] / src / interp.cpp
blob926d160e8ea038c5cf577fe94d73013a819b5408
2 #include "private.h"
3 #include "builtin.h"
5 namespace Aqua
7 using namespace Builtins;
8 using Value = Interpreter::Value;
10 static void populate_modpath(Interpreter& ip)
12 ip.addModulePath(".");
13 ip.addModulePath("./modules");
16 template<typename Stream>
17 static Value make_standard_handle(Interpreter* ip, Stream& strm)
19 auto tb = ip->makeTable();
20 tb->set(ID_HANDLE, ip->makeUserPointer(&strm));
21 for(auto pair: Builtins::FileMembers)
23 tb->set(pair.first, ip->makeFunction(pair.second));
25 return tb;
28 Value Interpreter::makeString(const std::string& src)
30 return Value(src);
33 Value Interpreter::makeNumber(Value::NumberType val)
35 return Value(Value::NumberType(val));
38 std::shared_ptr<Array<Value>> Interpreter::makeArray()
40 return std::make_shared<Array<Value>>();
43 std::shared_ptr<Table<Value>> Interpreter::makeTable()
45 return std::make_shared<Table<Value>>();
48 Value Interpreter::makeFunction(Interpreter::FuncProto fun)
50 auto node = std::make_shared<Internal::Function<Iter,Value,FuncType>>();
51 node->begin = node->end;
52 auto nop = std::make_shared<Internal::Nop<Iter,Value,FuncType>>();
53 nop->begin = nop->end;
54 node->children[0] = nop;
55 auto builtin = std::make_shared<Internal::BuiltinFunction<Iter,Value,FuncType>>();
56 builtin->begin = builtin->end;
57 builtin->function = fun;
58 node->children[1] = builtin;
59 return Value(Value::Type::Function, node);
62 bool Interpreter::need(const Value& raw_in, Value& dest, Value::Type expected)
64 auto intype = raw_in.type();
65 if(intype == expected)
67 dest = raw_in;
68 return true;
70 return false;
73 bool Interpreter::needNumber(const Value& raw_in, Value& dest)
75 return need(raw_in, dest, Value::Type::Number);
78 bool Interpreter::needString(const Value& raw_in, Value& dest)
80 return need(raw_in, dest, Value::Type::String);
83 bool Interpreter::needFunction(const Value& raw_in, Value& dest)
85 return need(raw_in, dest, Value::Type::Function);
88 void Interpreter::beginLocalScope()
90 m_envstack.push_back(std::make_shared<Table<Value>>());
93 void Interpreter::endLocalScope()
95 m_envstack.pop_back();
98 void Interpreter::beginFunctionScope()
100 m_funstack.push_back(m_envstack.size());
101 m_envstack.push_back(std::make_shared<Table<Value>>());
104 void Interpreter::endFunctionScope()
106 m_envstack.pop_back();
107 m_funstack.pop_back();
110 Value Interpreter::get(Value key)
112 int top = m_envstack.size()-1;
113 int bottom = m_funstack.back();
114 for(int i = top; i>=bottom; --i)
116 Value value = m_envstack[i]->get(key);
117 if(value.type() != Value::Type::Nil)
119 return value;
122 return m_envstack[0]->get(key);
125 void Interpreter::set(Value key, Value value)
127 m_envstack[m_funstack.back()]->set(key, value);
130 void Interpreter::setLocal(Value key, Value value)
132 m_envstack.back()->set(key, value);
135 void Interpreter::setGlobal(Value key, Value value)
137 m_envstack[0]->set(key, value);
140 void Interpreter::setGlobalFunc(const std::string &name, Interpreter::FuncProto fun)
142 setGlobal(Value(name), makeFunction(fun));
145 Interpreter::ModulePath Interpreter::getModulePath()
147 return m_modpath;
150 void Interpreter::addModulePath(const std::string& path)
152 m_modpath.push_back(path);
155 Interpreter::Interpreter()
157 beginFunctionScope();
158 populate_modpath(*this);
159 setGlobal(Value("true"), Value(Value::NumberType(1)));
160 setGlobal(Value("false"), Value(Value::NumberType(0)));
161 setGlobalFunc("print", Stdlib::fn_print);
162 setGlobalFunc("println", Stdlib::fn_println);
163 setGlobalFunc("readline", Stdlib::fn_readline);
164 setGlobalFunc("children", Stdlib::fn_children);
165 setGlobalFunc("tokens", Stdlib::fn_tokens);
166 setGlobalFunc("expand_node", Stdlib::fn_expand_node);
167 setGlobalFunc("tostring", Stdlib::fn_tostring);
168 setGlobalFunc("tonumber", Stdlib::fn_tonumber);
169 // this creates the "File" class
170 setGlobalFunc("File", OBJMEMBER_NAME(File, constructor));
172 // setting up IO table
173 auto iotb = makeTable();
174 iotb->set(makeString("stdout"), make_standard_handle(this, std::cout));
175 iotb->set(makeString("stderr"), make_standard_handle(this, std::cerr));
176 iotb->set(makeString("stdin"), make_standard_handle(this, std::cin));
177 setGlobal(makeString("IO"), iotb);
180 Interpreter::~Interpreter()
182 endFunctionScope();
185 Value Interpreter::eval(const std::string &source)
187 (void)source;
188 //LocalScope scope(*this);
189 #if 1
190 //auto psr = m_parser(source.begin(), source.end());
191 //auto root = m_parser.eval()->children[0];
192 //return (*this)(*root);
193 //return root->accept(*this);
194 //return result;
195 //return root->tree()->accept(*this);
196 //return_t parse_expression(StrIter sbegin, StrIter send)
197 //auto node = std::make_shared<Internal::Eval<Iter,Value,FuncType>>();
198 #else
199 ParserInstance ps;
200 ps(source.begin(), source.end());
201 Value result = ps.eval()->accept(*this);
202 return result;
203 #endif
204 return Value();
209 Value Interpreter::run(const std::string &source)
211 auto root = m_parser(source.begin(), source.end());
212 Value result = root->accept(*this);
213 return result;