'standardizing' awful macro usage
[aqualang.git] / src / interp.cpp
blob3585a34dcc630238119c9bc9bd2ee8418f82d532
2 #include "private.h"
3 #include "builtin.h"
5 using namespace Builtins;
6 using Value = Interpreter::Value;
8 static void populate_modpath(Interpreter& ip)
10 ip.addModulePath(".");
11 ip.addModulePath("./modules");
14 template<typename Stream>
15 static Value make_standard_handle(Interpreter* ip, Stream& strm)
17 auto tb = ip->makeTable();
18 tb->set(ID_HANDLE, ip->makeUserPointer(&strm));
19 for(auto pair: Builtins::FileMembers)
21 tb->set(pair.first, ip->makeFunction(pair.second));
23 return tb;
26 Value Interpreter::makeString(const std::string& src)
28 return Value(src);
31 Value Interpreter::makeNumber(Value::NumberType val)
33 return Value(Value::NumberType(val));
36 std::shared_ptr<Array<Value>> Interpreter::makeArray()
38 return std::make_shared<Array<Value>>();
41 std::shared_ptr<Table<Value>> Interpreter::makeTable()
43 return std::make_shared<Table<Value>>();
46 Value Interpreter::makeFunction(Interpreter::FuncProto fun)
48 auto node = std::make_shared<Internal::Function<Iter,Value,FuncType>>();
49 node->begin = node->end;
50 auto nop = std::make_shared<Internal::Nop<Iter,Value,FuncType>>();
51 nop->begin = nop->end;
52 node->children[0] = nop;
53 auto builtin = std::make_shared<Internal::BuiltinFunction<Iter,Value,FuncType>>();
54 builtin->begin = builtin->end;
55 builtin->function = fun;
56 node->children[1] = builtin;
57 return Value(Value::Type::Function, node);
60 bool Interpreter::need(const Value& raw_in, Value& dest, Value::Type expected)
62 auto intype = raw_in.type();
63 if(intype == expected)
65 dest = raw_in;
66 return true;
68 return false;
71 bool Interpreter::needNumber(const Value& raw_in, Value& dest)
73 return need(raw_in, dest, Value::Type::Number);
76 bool Interpreter::needString(const Value& raw_in, Value& dest)
78 return need(raw_in, dest, Value::Type::String);
81 bool Interpreter::needFunction(const Value& raw_in, Value& dest)
83 return need(raw_in, dest, Value::Type::Function);
86 void Interpreter::beginLocalScope()
88 m_envstack.push_back(std::make_shared<Table<Value>>());
91 void Interpreter::endLocalScope()
93 m_envstack.pop_back();
96 void Interpreter::beginFunctionScope()
98 m_funstack.push_back(m_envstack.size());
99 m_envstack.push_back(std::make_shared<Table<Value>>());
102 void Interpreter::endFunctionScope()
104 m_envstack.pop_back();
105 m_funstack.pop_back();
108 Value Interpreter::get(Value key)
110 int top = m_envstack.size()-1;
111 int bottom = m_funstack.back();
112 for(int i = top; i>=bottom; --i)
114 Value value = m_envstack[i]->get(key);
115 if(value.type() != Value::Type::Nil)
117 return value;
120 return m_envstack[0]->get(key);
123 void Interpreter::set(Value key, Value value)
125 m_envstack[m_funstack.back()]->set(key, value);
128 void Interpreter::setLocal(Value key, Value value)
130 m_envstack.back()->set(key, value);
133 void Interpreter::setGlobal(Value key, Value value)
135 m_envstack[0]->set(key, value);
138 void Interpreter::setGlobalFunc(const std::string &name, Interpreter::FuncProto fun)
140 setGlobal(Value(name), makeFunction(fun));
143 Interpreter::ModulePath Interpreter::getModulePath()
145 return m_modpath;
148 void Interpreter::addModulePath(const std::string& path)
150 m_modpath.push_back(path);
153 Interpreter::Interpreter()
155 beginFunctionScope();
156 populate_modpath(*this);
157 setGlobal(Value("true"), Value(Value::NumberType(1)));
158 setGlobal(Value("false"), Value(Value::NumberType(0)));
159 setGlobalFunc("print", Stdlib::fn_print);
160 setGlobalFunc("println", Stdlib::fn_println);
161 setGlobalFunc("readline", Stdlib::fn_readline);
162 setGlobalFunc("children", Stdlib::fn_children);
163 setGlobalFunc("tokens", Stdlib::fn_tokens);
164 setGlobalFunc("expand_node", Stdlib::fn_expand_node);
165 setGlobalFunc("tostring", Stdlib::fn_tostring);
166 setGlobalFunc("tonumber", Stdlib::fn_tonumber);
167 // this creates the "File" class
168 setGlobalFunc("File", OBJMEMBER_NAME(File, constructor));
170 // setting up IO table
171 auto iotb = makeTable();
172 iotb->set(makeString("stdout"), make_standard_handle(this, std::cout));
173 iotb->set(makeString("stderr"), make_standard_handle(this, std::cerr));
174 iotb->set(makeString("stdin"), make_standard_handle(this, std::cin));
175 setGlobal(makeString("IO"), iotb);
178 Interpreter::~Interpreter()
180 endFunctionScope();
183 Value Interpreter::eval(const std::string &source)
185 //LocalScope scope(*this);
186 #if 1
187 //auto psr = m_parser(source.begin(), source.end());
188 //auto root = m_parser.eval()->children[0];
189 //return (*this)(*root);
190 //return root->accept(*this);
191 //return result;
192 //return root->tree()->accept(*this);
193 //return_t parse_expression(StrIter sbegin, StrIter send)
194 //auto node = std::make_shared<Internal::Eval<Iter,Value,FuncType>>();
195 #else
196 ParserInstance ps;
197 ps(source.begin(), source.end());
198 Value result = ps.eval()->accept(*this);
199 return result;
200 #endif
201 return Value();
206 Value Interpreter::run(const std::string &source)
208 auto root = m_parser(source.begin(), source.end());
209 Value result = root->accept(*this);
210 return result;