18 return (o !=
nullptr) && ((
reinterpret_cast<intptr_t
>(o) & 7) == 0);
47 Obj args[] = { o0, o1 };
56 Obj args[] = { o0, o1, o2 };
65 Obj args[] = { o0, o1, o2, o3 };
74 Obj args[] = { o0, o1, o2, o3, o4 };
84 Obj args[] = { o0, o1, o2, o3, o4, o5 };
94 Obj args[] = { o0, o1, o2, o3, o4, o5, o6 };
104 Obj args[] = { o0, o1, o2, o3, o4, o5, o6, o7 };
114 Obj args[] = { o0, o1, o2, o3, o4, o5, o6, o7, o8 };
124 Obj args[] = { o0, o1, o2, o3, o4, o5, o6, o7, o8, o9 };
155 Obj args[] = { o0, o1 };
166 Obj args[] = { o0, o1, o2 };
177 Obj args[] = { o0, o1, o2, o3 };
189 Obj args[] = { o0, o1, o2, o3, o4 };
201 Obj args[] = { o0, o1, o2, o3, o4, o5 };
213 Obj args[] = { o0, o1, o2, o3, o4, o5, o6 };
225 Obj args[] = { o0, o1, o2, o3, o4, o5, o6, o7 };
237 Obj args[] = { o0, o1, o2, o3, o4, o5, o6, o7, o8 };
249 Obj args[] = { o0, o1, o2, o3, o4, o5, o6, o7, o8, o9 };
290 void Value::set(
Obj o)
294 assert(holder !=
nullptr);
300 assert(holder ==
nullptr);
304 holder =
reinterpret_cast<Obj*
>(GC_malloc_uncollectable(
sizeof(
Obj)));
317 assert(holder !=
nullptr);
321 Obj *Context::lookupSymbol(
const std::string &name)
326 if (!symbols.empty())
328 auto top = symbols.back();
329 auto I = top->find(name);
336 auto I = globalSymbols.find(name);
337 if (I != globalSymbols.end())
345 void Context::setSymbol(
const std::string &name,
Obj val)
347 Obj *addr = lookupSymbol(name);
353 globals.emplace_front(val);
356 addr = globals.front().address();
357 globalSymbols[name] = addr;
365 void Context::setSymbol(
const std::string &name,
Obj *val)
367 (*symbols.back())[name] = val;
378 for (
auto &s : statements)
390 std::unordered_set<std::string> &uses)
392 for (
auto &s : statements)
394 s->collectVarUses(decls, uses);
407 Obj r = evaluateExpr(c);
409 if (isConstantExpression())
422 Obj obj = callee->evaluate(c);
424 auto &argsAST = arguments->arguments;
427 for (
auto &Arg : argsAST)
429 assert(i<(
sizeof(args)/
sizeof(
Obj)));
430 args[i++] = Arg->evaluate(c);
457 void ClosureDecl::check()
466 body->collectVarUses(decls, boundVars);
468 for (
auto ¶m : parameters->arguments)
470 boundVars.erase(*param.get());
474 for (
auto &decl : decls)
476 boundVars.erase(decl);
481 void ClosureDecl::collectVarUses(std::unordered_set<std::string> &decls,
482 std::unordered_set<std::string> &uses)
487 uses.insert(boundVars.begin(), boundVars.end());
502 Closure *C = gcAlloc<Closure>(boundVars.size() *
sizeof(
Obj));
506 size_t params = parameters->arguments.size();
509 C->
invoke = compiledClosure ? compiledClosure :
511 c.
setSymbol(name, reinterpret_cast<Obj>(C));
514 for (
auto &var : boundVars)
518 return reinterpret_cast<Obj>(C);
537 self, sel, args, parameters->arguments.size());
544 for (
auto ¶m : parameters->arguments)
553 Obj *ivars = (
reinterpret_cast<Obj*
>(&
self->isa)) + 1;
582 compiledClosure =
self->invoke;
588 parameters->arguments.size());
595 for (
auto ¶m : parameters->arguments)
601 for (
auto &bound : boundVars)
604 c.
setSymbol(bound, &self->boundVars[i++]);
623 String *str = gcAlloc<String>(size());
624 assert(str !=
nullptr);
631 return reinterpret_cast<Obj>(str);
636 if ((reinterpret_cast<intptr_t>(condition->evaluate(c))) & ~7)
643 while (!c.
isReturning && (reinterpret_cast<intptr_t>(condition->evaluate(c))) & ~7)
655 v = init->evaluate(c);
662 c.
setSymbol(target->name, expr->evaluate(c));
667 Obj LHS = lhs->evaluate(c);
668 Obj RHS = rhs->evaluate(c);
679 (reinterpret_cast<intptr_t>(LHS)) >> 3,
680 (reinterpret_cast<intptr_t>(RHS)) >> 3));
694 c.
retVal = expr->evaluate(c);
705 std::string &clsName = name ? *name : superclassName;
707 cls->
className = strdup(clsName.c_str());
718 for (
auto &m : methods)
721 method->
args = m->parameters->arguments.size();
726 assert(method->
args <= 10);
731 method->
AST = m.get();
745 for (
auto &i : ivars)
747 *(ivar++) = strdup(i->name.c_str());
Obj closureTrampoline8(Closure *C, Obj o0, Obj o1, Obj o2, Obj o3, Obj o4, Obj o5, Obj o6, Obj o7)
8-argument trampoline for jumping back into the interpreter when a closure that has not yet been comp...
Obj closureTrampoline3(Closure *C, Obj o0, Obj o1, Obj o2)
3-argument trampoline for jumping back into the interpreter when a closure that has not yet been comp...
void interpret(Interpreter::Context &c) override
Interpret the assignment, updating the stored value.
struct Class * isa
The pointer to the class of this object.
Object *(* CompiledMethod)(Object *, Selector,...)
A compiled method is a function that takes an object (the receiver) and the selector as implicit argu...
Obj methodTrampoline1(Obj self, Selector cmd, Obj o0)
1-argument trampoline for jumping back into the interpreter when a method that has not yet been compi...
Object * Obj
Object pointer.
Obj closureTrampoline4(Closure *C, Obj o0, Obj o1, Obj o2, Obj o3)
4-argument trampoline for jumping back into the interpreter when a closure that has not yet been comp...
Obj callCompiledClosure(ClosureInvoke m, Closure *receiver, Obj *args, int argCount)
Calls a compiled closure from the specified argument list.
Obj evaluateExpr(Interpreter::Context &c) override
Evaluate this by looking up the variable in the interpreter's symbol table and loading it...
Value retVal
The value currently being returned, if there is one.
CompiledMethod methodTrampolines[]
Array of trampolines, indexed by number or arguments.
uint32_t Selector
Selectors are unique identifiers for methods.
AST::ClosureDecl * AST
The AST for this closure.
void popSymbols()
Pop the top symbol table off the stack.
bool needsGC(Obj o)
Indicates whether a particular object needs to be visible to the GC.
const char ** indexedIVarNames
The names of the instance variables.
void interpret(Interpreter::Context &c)
Interprets each of the statements in turn.
ClosureInvoke invoke
The function that is used to invoke this closure.
Obj closureTrampoline9(Closure *C, Obj o0, Obj o1, Obj o2, Obj o3, Obj o4, Obj o5, Obj o6, Obj o7, Obj o8)
9-argument trampoline for jumping back into the interpreter when a closure that has not yet been comp...
Obj closureTrampoline2(Closure *C, Obj o0, Obj o1)
2-argument trampoline for jumping back into the interpreter when a closure that has not yet been comp...
struct Class SmallIntClass
The SmallInt (Number) class structure.
void interpret(Interpreter::Context &c) override
Sets the variable to the value in the initialisation.
Obj methodTrampoline4(Obj self, Selector cmd, Obj o0, Obj o1, Obj o2, Obj o3)
4-argument trampoline for jumping back into the interpreter when a method that has not yet been compi...
std::unordered_map< std::string, Obj * > SymbolTable
A symbol table stores the address of each allocation.
Obj methodTrampoline8(Obj self, Selector cmd, Obj o0, Obj o1, Obj o2, Obj o3, Obj o4, Obj o5, Obj o6, Obj o7)
8-argument trampoline for jumping back into the interpreter when a method that has not yet been compi...
Class * isa
Class pointer.
Obj evaluateExpr(Interpreter::Context &c) override
Evaluate the.
struct Method * methodList
An array of methodCount elements describing the methods that this class implements.
Obj evaluateExpr(Interpreter::Context &c) override
Call the relevant method or closure.
Selector lookupSelector(const std::string &str)
Looks up the selector for a specified string value, registering a new value if this is the first time...
Interpreter::Context * currentContext
Obj newObject(struct Class *cls)
Instantiate an object.
Object *(* ClosureInvoke)(Closure *,...)
A compiled closure invoke function.
Obj methodTrampoline7(Obj self, Selector cmd, Obj o0, Obj o1, Obj o2, Obj o3, Obj o4, Obj o5, Obj o6)
7-argument trampoline for jumping back into the interpreter when a method that has not yet been compi...
Obj boundVars[0]
An array of bound variables in this closure.
void registerClass(const std::string &name, struct Class *cls)
Register a newly constructed class.
Obj closureTrampoline1(Closure *C, Obj o0)
1-argument trampoline for jumping back into the interpreter when a closure that has not yet been comp...
void interpret(Interpreter::Context &c) override
Interpret, but constructing the class.
Obj evaluate(Interpreter::Context &c)
Evaluate the expression, caching the result if it's a constant expression.
struct Class * lookupClass(const std::string &name)
Look up an existing class.
Obj interpretClosure(Interpreter::Context &c, MysoreScript::Closure *self, Obj *args)
Interprets the closure in the current context.
A generic MysoreScript object.
Obj evaluateExpr(Interpreter::Context &c) override
Evaluates the expression, either invoking a subclass evaluateWithIntegers method or by calling the re...
Obj * lookupSymbol(const std::string &name)
Look up a symbol, walking up the symbol table stack until it's found.
AST::ClosureDecl * AST
The AST for this method.
bool isReturning
Are we currently returning?
bool forceCompiler
Force the compiler to run.
Obj methodTrampoline5(Obj self, Selector cmd, Obj o0, Obj o1, Obj o2, Obj o3, Obj o4)
5-argument trampoline for jumping back into the interpreter when a method that has not yet been compi...
int32_t args
The number of arguments that this method takes.
struct Class StringClass
The String class structure.
struct Class ClosureClass
The Closure class structure.
Obj methodTrampoline6(Obj self, Selector cmd, Obj o0, Obj o1, Obj o2, Obj o3, Obj o4, Obj o5)
6-argument trampoline for jumping back into the interpreter when a method that has not yet been compi...
Obj methodTrampoline3(Obj self, Selector cmd, Obj o0, Obj o1, Obj o2)
3-argument trampoline for jumping back into the interpreter when a method that has not yet been compi...
ClosureInvoke closureTrampolines[]
Array of trampolines, indexed by number or arguments.
CompiledMethod function
The compiled method, if one exists.
Obj methodTrampoline10(Obj self, Selector cmd, Obj o0, Obj o1, Obj o2, Obj o3, Obj o4, Obj o5, Obj o6, Obj o7, Obj o8, Obj o9)
10-argument trampoline for jumping back into the interpreter when a method that has not yet been comp...
Method * methodForSelector(Class *cls, Selector sel)
Looks up the Method that should be invoked for the specified selector on this class.
Obj evaluateExpr(Interpreter::Context &c) override
Evaluate this closure, returning the closure object representing it.
void setSymbol(const std::string &name, Obj *val)
Set the address where the variable corresponding to a particular symbol is stored.
CompiledMethod compiledMethodForSelector(Obj obj, Selector sel)
Look up the compiled method to call for a specific selector.
Class * isa
Class pointer.
Obj interpretMethod(Interpreter::Context &c, MysoreScript::Method *mth, Obj self, MysoreScript::Selector sel, Obj *args)
Interprets the closure, assuming that it is a method.
Obj closureTrampoline7(Closure *C, Obj o0, Obj o1, Obj o2, Obj o3, Obj o4, Obj o5, Obj o6)
7-argument trampoline for jumping back into the interpreter when a closure that has not yet been comp...
Obj callCompiledMethod(CompiledMethod m, Obj receiver, Selector sel, Obj *args, int argCount)
Calls a compiled method, constructing the correct argument frame based on the arguments.
char characters[0]
An array of characters.
struct Class * superclass
The superclass of this class, if it has one, or a null pointer if it is a root class.
void interpret(Interpreter::Context &c) override
Interpret the returned expression and then indicate in the context that we have hit a return statemen...
Obj closureTrampoline10(Closure *C, Obj o0, Obj o1, Obj o2, Obj o3, Obj o4, Obj o5, Obj o6, Obj o7, Obj o8, Obj o9)
10-argument trampoline for jumping back into the interpreter when a closure that has not yet been com...
int32_t methodCount
The number of methods that this class implements.
The primitive String class in MysoreScript.
int32_t indexedIVarCount
The number of indexed instance variables that this class has.
void interpret(Interpreter::Context &c) override
Interpret the condition, then interpret the body if the condition is true.
Obj methodTrampoline2(Obj self, Selector cmd, Obj o0, Obj o1)
2-argument trampoline for jumping back into the interpreter when a method that has not yet been compi...
Obj closureTrampoline6(Closure *C, Obj o0, Obj o1, Obj o2, Obj o3, Obj o4, Obj o5)
6-argument trampoline for jumping back into the interpreter when a closure that has not yet been comp...
const char * className
The name of this class.
Obj createSmallInteger(intptr_t i)
Construct a small integer object from the given integer.
void collectVarUses(std::unordered_set< std::string > &decls, std::unordered_set< std::string > &uses)
Visits each statement to collect its variable uses and definitions.
Obj closureTrampoline5(Closure *C, Obj o0, Obj o1, Obj o2, Obj o3, Obj o4)
5-argument trampoline for jumping back into the interpreter when a closure that has not yet been comp...
void interpret(Interpreter::Context &c) override
Interpret the body as long as the condition remains true.
void pushSymbols(SymbolTable &s)
Push a new symbol table on top of the stack.
Obj methodTrampoline9(Obj self, Selector cmd, Obj o0, Obj o1, Obj o2, Obj o3, Obj o4, Obj o5, Obj o6, Obj o7, Obj o8)
9-argument trampoline for jumping back into the interpreter when a method that has not yet been compi...
Obj length
The number of characters in the string.
Struct holding metadata about a class.
Methods in a class's method list.
SymbolTable globalSymbols
Global symbols.
Obj closureTrampoline0(Closure *C)
0-argument trampoline for jumping back into the interpreter when a closure that has not yet been comp...
bool isInteger(Obj o)
Is this object a small integer (lowest bit is 1, next two bits are 0).
Obj parameters
The number of parameters that this object has.
Obj methodTrampoline0(Obj self, Selector cmd)
0-argument trampoline for jumping back into the interpreter when a method that has not yet been compi...
The layout of all closures in MysoreScript.
Selector selector
The selector that this method applies to.