MysoreScript
ast.hh
Go to the documentation of this file.
1 #include "Pegmatite/ast.hh"
2 #include "runtime.hh"
3 #include "interpreter.hh"
4 #include <unordered_set>
5 #include <functional>
6 
7 namespace Compiler
8 {
9  class Context;
10 }
11 
12 namespace llvm
13 {
14  class Value;
15 }
16 
17 namespace AST
18 {
19  using pegmatite::ASTPtr;
20  using pegmatite::ASTChild;
21  using pegmatite::ASTList;
22  using pegmatite::ErrorReporter;
23  using MysoreScript::Obj;
24 
28  struct Statement : pegmatite::ASTContainer
29  {
33  virtual void interpret(Interpreter::Context &c) = 0;
37  virtual void compile(Compiler::Context &c) {}
44  virtual void collectVarUses(std::unordered_set<std::string> &decls,
45  std::unordered_set<std::string> &uses) = 0;
46  };
47 
52  class Expression : public Statement
53  {
54  protected:
62  virtual Obj evaluateExpr(Interpreter::Context &c) = 0;
63  public:
69  virtual bool isConstantExpression() { return false; }
74  Obj evaluate(Interpreter::Context &c);
78  void interpret(Interpreter::Context &c) override final
79  {
80  evaluate(c);
81  }
85  void compile(Compiler::Context &c) override final
86  {
87  compileExpression(c);
88  }
93  virtual llvm::Value *compileExpression(Compiler::Context &c) = 0;
94  };
98  struct Statements : pegmatite::ASTContainer
99  {
104  void interpret(Interpreter::Context &c);
108  void compile(Compiler::Context &c);
112  void collectVarUses(std::unordered_set<std::string> &decls,
113  std::unordered_set<std::string> &uses);
114  private:
118  ASTList<Statement> statements;
119  };
123  struct Number : public Expression
124  {
129  int64_t value;
134  bool construct(const pegmatite::InputRange &r,
135  pegmatite::ASTStack &st, const ErrorReporter&) override
136  {
137  pegmatite::constructValue(r, value);
138  return true;
139  }
143  bool isConstantExpression() override { return true; }
144  protected:
150  {
151  return reinterpret_cast<Obj>((value << 3) | 1);
152  }
156  llvm::Value *compileExpression(Compiler::Context &c) override;
160  void collectVarUses(std::unordered_set<std::string> &decls,
161  std::unordered_set<std::string> &uses) override
162  {
163  return;
164  }
165  };
170  struct StringLiteral : public Expression, pegmatite::ASTString
171  {
175  bool construct(const pegmatite::InputRange &r,
176  pegmatite::ASTStack &st, const ErrorReporter &er) override
177  {
178  pegmatite::ASTString::construct(r, st, er);
179  std::string::size_type newline;
180  while ((newline = find("\\n")) != std::string::npos)
181  {
182  replace(newline, 2, "\n");
183  }
184  return true;
185  }
189  bool isConstantExpression() override { return true; }
193  Obj evaluateExpr(Interpreter::Context &c) override;
198  llvm::Value *compileExpression(Compiler::Context &c) override;
202  void collectVarUses(std::unordered_set<std::string> &decls,
203  std::unordered_set<std::string> &uses) override
204  {
205  return;
206  }
207  };
211  struct BinOpBase : public Expression
212  {
216  ASTPtr<Expression> lhs;
220  ASTPtr<Expression> rhs;
226  virtual bool isComparison() { return false; }
234  bool isConstantExpression() override
235  {
236  return lhs->isConstantExpression() && rhs->isConstantExpression();
237  }
243  Obj evaluateExpr(Interpreter::Context &c) override;
248  virtual llvm::Value *compileBinOp(Compiler::Context &c,
249  llvm::Value *LHS,
250  llvm::Value *RHS) = 0;
255  llvm::Value *compileExpression(Compiler::Context &c) override
256  {
257  return compileBinOp(c,
258  lhs->compileExpression(c),
259  rhs->compileExpression(c));
260  }
265  virtual const char *methodName() = 0;
271  void collectVarUses(std::unordered_set<std::string> &decls,
272  std::unordered_set<std::string> &uses) override
273  {
274  lhs->collectVarUses(decls, uses);
275  rhs->collectVarUses(decls, uses);
276  }
281  virtual intptr_t evaluateWithIntegers(intptr_t lhs, intptr_t rhs) = 0;
282  };
288  template<class Op>
289  struct BinOp : public BinOpBase
290  {
295  intptr_t evaluateWithIntegers(intptr_t lhs, intptr_t rhs) override
296  {
297  Op o;
298  return o(lhs, rhs);
299  }
300  };
304  struct Multiply : public BinOp<std::multiplies<intptr_t>>
305  {
310  const char *methodName() override { return "mul"; }
314  llvm::Value *compileBinOp(Compiler::Context &c,
315  llvm::Value *LHS,
316  llvm::Value *RHS) override;
317  };
321  struct Divide : public BinOp<std::divides<intptr_t>>
322  {
327  const char *methodName() override { return "div"; }
331  llvm::Value *compileBinOp(Compiler::Context &c,
332  llvm::Value *LHS,
333  llvm::Value *RHS) override;
334  };
338  struct Add : public BinOp<std::plus<intptr_t>>
339  {
344  const char *methodName() override { return "add"; }
348  llvm::Value *compileBinOp(Compiler::Context &c,
349  llvm::Value *LHS,
350  llvm::Value *RHS) override;
351  };
355  struct Subtract : public BinOp<std::minus<intptr_t>>
356  {
361  intptr_t evaluateWithIntegers(intptr_t lhs, intptr_t rhs) override
362  {
363  return lhs - rhs;
364  }
369  const char *methodName() override { return "sub"; }
373  llvm::Value *compileBinOp(Compiler::Context &c,
374  llvm::Value *LHS,
375  llvm::Value *RHS) override;
376  };
380  template<class T>
381  struct Comparison : public BinOp<T>
382  {
386  bool isComparison() override { return true; }
390  const char *methodName() override { return nullptr; }
391  };
395  struct CmpEq : public Comparison<std::equal_to<intptr_t>>
396  {
397  llvm::Value *compileBinOp(Compiler::Context &c,
398  llvm::Value *LHS,
399  llvm::Value *RHS) override;
400  };
404  struct CmpNe : public Comparison<std::not_equal_to<intptr_t>>
405  {
406  llvm::Value *compileBinOp(Compiler::Context &c,
407  llvm::Value *LHS,
408  llvm::Value *RHS) override;
409  };
413  struct CmpLt : public Comparison<std::less<intptr_t>>
414  {
415  llvm::Value *compileBinOp(Compiler::Context &c,
416  llvm::Value *LHS,
417  llvm::Value *RHS) override;
418  };
422  struct CmpGt : public Comparison<std::greater<intptr_t>>
423  {
424  llvm::Value *compileBinOp(Compiler::Context &c,
425  llvm::Value *LHS,
426  llvm::Value *RHS) override;
427  };
431  struct CmpLE : public Comparison<std::less_equal<intptr_t>>
432  {
433  llvm::Value *compileBinOp(Compiler::Context &c,
434  llvm::Value *LHS,
435  llvm::Value *RHS) override;
436  };
440  struct CmpGE : public Comparison<std::greater_equal<intptr_t>>
441  {
442  llvm::Value *compileBinOp(Compiler::Context &c,
443  llvm::Value *LHS,
444  llvm::Value *RHS) override;
445  };
451  struct Identifier : public pegmatite::ASTString { };
462  struct ParamList : public pegmatite::ASTContainer
463  {
467  ASTList<Identifier> arguments;
468  };
474  {
478  ASTChild<Identifier> name;
482  ASTPtr<ParamList> parameters;
486  ASTPtr<Statements> body;
492  Obj interpretClosure(Interpreter::Context &c,
493  MysoreScript::Closure *self,
494  Obj *args);
500  Obj interpretMethod(Interpreter::Context &c,
502  Obj self,
504  Obj *args);
505  protected:
511  Obj evaluateExpr(Interpreter::Context &c) override;
517  llvm::Value *compileExpression(Compiler::Context &c) override;
518  private:
527  static const int compileThreshold = 10;
532  int executionCount = 0;
537  MysoreScript::ClosureInvoke compiledClosure = nullptr;
542  bool checked = false;
547  void check();
552  std::unordered_set<std::string> boundVars;
556  std::unordered_set<std::string> decls;
561  Interpreter::SymbolTable &globalSymbols);
565  MysoreScript::ClosureInvoke compileClosure(Interpreter::SymbolTable &globalSymbols);
570  void collectVarUses(std::unordered_set<std::string> &decls,
571  std::unordered_set<std::string> &uses) override;
572  };
576  struct VarRef : public Expression
577  {
581  ASTChild<Identifier> name;
585  void collectVarUses(std::unordered_set<std::string> &decls,
586  std::unordered_set<std::string> &uses) override
587  {
588  uses.insert(name);
589  }
590  protected:
595  Obj evaluateExpr(Interpreter::Context &c) override;
600  llvm::Value *compileExpression(Compiler::Context &c) override;
601  };
607  {
611  ASTPtr<VarRef> target;
615  ASTPtr<Expression> expr;
619  void interpret(Interpreter::Context &c) override;
624  void compile(Compiler::Context &c) override;
628  void collectVarUses(std::unordered_set<std::string> &decls,
629  std::unordered_set<std::string> &uses) override
630  {
631  target->collectVarUses(decls, uses);
632  expr->collectVarUses(decls, uses);
633  }
634  };
639  struct ArgList : public pegmatite::ASTContainer
640  {
645  ASTList<Expression> arguments;
646  };
650  struct Call : public Expression
651  {
656  ASTPtr<Expression> callee;
660  ASTPtr<Identifier, /*optional*/true> method;
664  ASTPtr<ArgList> arguments;
665  protected:
669  Obj evaluateExpr(Interpreter::Context &c) override;
673  llvm::Value *compileExpression(Compiler::Context &c) override;
677  void collectVarUses(std::unordered_set<std::string> &decls,
678  std::unordered_set<std::string> &uses) override
679  {
680  callee->collectVarUses(decls, uses);
681  for (auto &arg : arguments->arguments)
682  {
683  arg->collectVarUses(decls, uses);
684  }
685  }
686  };
690  struct Decl : Statement
691  {
695  ASTChild<Identifier> name;
699  ASTPtr<Expression, /*optional*/true> init;
703  void interpret(Interpreter::Context &c) override;
707  void compile(Compiler::Context &c) override;
711  void collectVarUses(std::unordered_set<std::string> &decls,
712  std::unordered_set<std::string> &uses) override
713  {
714  decls.insert(name);
715  }
716  };
720  struct Return : Statement
721  {
725  ASTPtr<Expression> expr;
730  void interpret(Interpreter::Context &c) override;
734  virtual void compile(Compiler::Context &c) override;
738  void collectVarUses(std::unordered_set<std::string> &decls,
739  std::unordered_set<std::string> &uses) override
740  {
741  expr->collectVarUses(decls, uses);
742  }
743  };
748  {
753  ASTPtr<Expression> condition;
757  ASTPtr<Statements> body;
762  void interpret(Interpreter::Context &c) override;
766  virtual void compile(Compiler::Context &c) override;
770  void collectVarUses(std::unordered_set<std::string> &decls,
771  std::unordered_set<std::string> &uses) override
772  {
773  condition->collectVarUses(decls, uses);
774  body->collectVarUses(decls, uses);
775  }
776  };
780  class WhileLoop : public Statement
781  {
786  ASTPtr<Expression> condition;
790  ASTPtr<Statements> body;
791  protected:
795  void interpret(Interpreter::Context &c) override;
799  void collectVarUses(std::unordered_set<std::string> &decls,
800  std::unordered_set<std::string> &uses) override
801  {
802  condition->collectVarUses(decls, uses);
803  body->collectVarUses(decls, uses);
804  }
808  void compile(Compiler::Context &c) override;
809  };
814  {
824  ASTPtr<Identifier, /*optional*/true> name;
828  ASTChild<Identifier> superclassName;
832  ASTList<Decl> ivars;
836  ASTList<ClosureDecl> methods;
842  void interpret(Interpreter::Context &c) override;
847  void collectVarUses(std::unordered_set<std::string> &decls,
848  std::unordered_set<std::string> &uses) override {}
849  };
853  class NewExpr : public Expression
854  {
858  ASTChild<Identifier> className;
862  Obj evaluateExpr(Interpreter::Context &c) override;
866  llvm::Value *compileExpression(Compiler::Context &c) override;
872  void collectVarUses(std::unordered_set<std::string> &decls,
873  std::unordered_set<std::string> &uses) override {}
874  };
875 }
ASTPtr< Expression > rhs
The right-hand side of the operation.
Definition: ast.hh:220
A class declaration.
Definition: ast.hh:813
ASTPtr< ParamList > parameters
The parameter list.
Definition: ast.hh:482
Add expression.
Definition: ast.hh:338
Abstract superclass for binary operators.
Definition: ast.hh:211
Abstract superclass for expressions (statements that evaluate to something).
Definition: ast.hh:52
const char * methodName() override
Add operations become add() method invocations on non-integer objects.
Definition: ast.hh:344
Object *(* CompiledMethod)(Object *, Selector,...)
A compiled method is a function that takes an object (the receiver) and the selector as implicit argu...
Definition: runtime.hh:75
Definition: ast.hh:12
ASTPtr< Statements > body
The body of the if statement.
Definition: ast.hh:757
ASTChild< Identifier > superclassName
The superclass name (or class name if there is no superclass).
Definition: ast.hh:828
Greater-than comparison.
Definition: ast.hh:422
Object * Obj
Object pointer.
Definition: runtime.hh:33
bool construct(const pegmatite::InputRange &r, pegmatite::ASTStack &st, const ErrorReporter &er) override
Construct the string from the source text.
Definition: ast.hh:175
bool isConstantExpression() override
A binary operation is a constant expression if both of its operands are binary expressions.
Definition: ast.hh:234
virtual bool isConstantExpression()
Returns true if the expression is constant and therefore doesn&#39;t need interpreting every time...
Definition: ast.hh:69
uint32_t Selector
Selectors are unique identifiers for methods.
Definition: runtime.hh:70
Non-equality comparison.
Definition: ast.hh:404
ASTPtr< Statements > body
The statements that make up the body of the closure.
Definition: ast.hh:486
Superclass for comparison operations.
Definition: ast.hh:381
Equality comparison.
Definition: ast.hh:395
A closure declaration.
Definition: ast.hh:473
A parameter list for a closure declaration.
Definition: ast.hh:462
ASTPtr< Expression > expr
The expression being assigned.
Definition: ast.hh:615
bool isComparison() override
All comparisons are (obviously) comparisons.
Definition: ast.hh:386
Interpreter::Value cache
Cached result for constant expression.
Definition: ast.hh:58
Multiply operation.
Definition: ast.hh:304
A new expression, which constructs a new instance of a class.
Definition: ast.hh:853
std::unordered_map< std::string, Obj * > SymbolTable
A symbol table stores the address of each allocation.
Definition: interpreter.hh:103
Assignment statements, setting the value of a variable.
Definition: ast.hh:606
void collectVarUses(std::unordered_set< std::string > &decls, std::unordered_set< std::string > &uses) override
Classes are not allowed to be declared inside closures, so there is never a need to collect their dec...
Definition: ast.hh:847
const char * methodName() override
Divide operations become div() method invocations on non-integer objects.
Definition: ast.hh:327
Argument list for a call expression.
Definition: ast.hh:639
ASTPtr< Identifier, true > method
The name of the method, if this is a method invocation.
Definition: ast.hh:660
The compiler context.
Definition: compiler.hh:16
Object *(* ClosureInvoke)(Closure *,...)
A compiled closure invoke function.
Definition: runtime.hh:80
void collectVarUses(std::unordered_set< std::string > &decls, std::unordered_set< std::string > &uses) override
Collect the uses and declarations in this expression.
Definition: ast.hh:271
bool isConstantExpression() override
Literals are constant expressions.
Definition: ast.hh:189
intptr_t evaluateWithIntegers(intptr_t lhs, intptr_t rhs) override
Evaluate on integer values by subtracting the right side from the left.
Definition: ast.hh:361
void interpret(Interpreter::Context &c) override final
Interpret this expression as if it were a statement.
Definition: ast.hh:78
Divide operation.
Definition: ast.hh:321
ASTChild< Identifier > name
The name of the referenced variable.
Definition: ast.hh:581
A number literal.
Definition: ast.hh:123
ASTPtr< Expression > expr
The expression that is returned.
Definition: ast.hh:725
Reference to a variable.
Definition: ast.hh:576
Template superclass for binary operators.
Definition: ast.hh:289
int64_t value
The value of this literal.
Definition: ast.hh:129
bool isConstantExpression() override
All literals are constant expressions.
Definition: ast.hh:143
Block of statements.
Definition: ast.hh:98
ASTPtr< Expression, true > init
The initialiser for this variable, if there is one.
Definition: ast.hh:699
const char * methodName() override
Comparisons don&#39;t map to any method name.
Definition: ast.hh:390
void collectVarUses(std::unordered_set< std::string > &decls, std::unordered_set< std::string > &uses) override
Collect any variables use in this expression.
Definition: ast.hh:628
Definition: ast.hh:7
Value wraps an object pointer.
Definition: interpreter.hh:25
If statement.
Definition: ast.hh:747
ASTPtr< Expression > callee
The callee, if this is calling a closure, or the object that is having a method invoked on it if it i...
Definition: ast.hh:656
A while loop.
Definition: ast.hh:780
void compile(Compiler::Context &c) override final
Compile this expression as if it were a statement.
Definition: ast.hh:85
void collectVarUses(std::unordered_set< std::string > &decls, std::unordered_set< std::string > &uses) override
Add this variable to the set of referenced variables.
Definition: ast.hh:585
ASTPtr< Expression > lhs
The left-hand side of the operation.
Definition: ast.hh:216
void collectVarUses(std::unordered_set< std::string > &decls, std::unordered_set< std::string > &uses) override
Collect any variables that are referenced.
Definition: ast.hh:738
virtual bool isComparison()
Returns whether this operation is a comparison.
Definition: ast.hh:226
void collectVarUses(std::unordered_set< std::string > &decls, std::unordered_set< std::string > &uses) override
Collect all of the variables used and defined in this statement.
Definition: ast.hh:770
A call expression.
Definition: ast.hh:650
const char * methodName() override
Subtract operations become sub() method invocations on non-integer objects.
Definition: ast.hh:369
Any identifier in the source.
Definition: ast.hh:451
void collectVarUses(std::unordered_set< std::string > &decls, std::unordered_set< std::string > &uses) override
Adds this variable to the set that are defined.
Definition: ast.hh:711
A variable declaration.
Definition: ast.hh:690
const char * methodName() override
Multiply operations become the mul() method invocations on non-integer objects.
Definition: ast.hh:310
ASTPtr< VarRef > target
The variable being assigned to.
Definition: ast.hh:611
ASTList< Decl > ivars
The instance variables declared in this class.
Definition: ast.hh:832
void collectVarUses(std::unordered_set< std::string > &decls, std::unordered_set< std::string > &uses) override
Collect the variables used and declared in the loop.
Definition: ast.hh:799
Definition: ast.hh:17
ASTList< Expression > arguments
The expressions that will be evaluated to give the arguments to the called function.
Definition: ast.hh:645
ASTChild< Identifier > name
The name of the variable.
Definition: ast.hh:695
llvm::Value * compileExpression(Compiler::Context &c) override
Compile the expression by compiling the two sides and then calling compileBinOp (implemented in subcl...
Definition: ast.hh:255
void collectVarUses(std::unordered_set< std::string > &decls, std::unordered_set< std::string > &uses) override
Collect the variables referenced by this call.
Definition: ast.hh:677
Less-than-or-equal-to comparison.
Definition: ast.hh:431
Greater-than-or-equal-to comparison.
Definition: ast.hh:440
bool construct(const pegmatite::InputRange &r, pegmatite::ASTStack &st, const ErrorReporter &) override
Constructs the class from the source range.
Definition: ast.hh:134
The abstract superclass for all statements.
Definition: ast.hh:28
void collectVarUses(std::unordered_set< std::string > &decls, std::unordered_set< std::string > &uses) override
Literals do not define or use any values.
Definition: ast.hh:202
ASTPtr< Expression > condition
The condition.
Definition: ast.hh:753
virtual void compile(Compiler::Context &c)
Compile this statement to LLVM IR.
Definition: ast.hh:37
intptr_t evaluateWithIntegers(intptr_t lhs, intptr_t rhs) override
Evaluate (interpret) this expression, having already determined that the two sides are integer values...
Definition: ast.hh:295
A string literal.
Definition: ast.hh:170
Return statement.
Definition: ast.hh:720
void collectVarUses(std::unordered_set< std::string > &decls, std::unordered_set< std::string > &uses) override
Literals do not define or use any values.
Definition: ast.hh:160
Subtract expression.
Definition: ast.hh:355
Struct holding metadata about a class.
Definition: runtime.hh:109
ASTList< Identifier > arguments
The arguments in this parameter list.
Definition: ast.hh:467
Obj evaluateExpr(Interpreter::Context &c) override
Construct the small integer (integer in a pointer with the low bit set to 1) value corresponding to t...
Definition: ast.hh:149
ASTPtr< ArgList > arguments
The arguments to this call.
Definition: ast.hh:664
Methods in a class&#39;s method list.
Definition: runtime.hh:85
Less-than comparison.
Definition: ast.hh:413
ASTPtr< Identifier, true > name
The name of the class.
Definition: ast.hh:824
ASTChild< Identifier > name
The name of this closure.
Definition: ast.hh:478
The layout of all closures in MysoreScript.
Definition: runtime.hh:199
ASTList< ClosureDecl > methods
The methods declared in this class.
Definition: ast.hh:836