summaryrefslogtreecommitdiff
path: root/source/slang/stmt-defs.h
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-06-29 08:55:09 -0700
committerTim Foley <tfoley@nvidia.com>2017-06-30 12:22:33 -0700
commitcab694dcead92a554654d7fa3f08909d519425f0 (patch)
tree6c2c07c3930ff68b5518e562b0b507d5ec54d0bf /source/slang/stmt-defs.h
parentb2b08679a32506d629df84730f36639dab9f9593 (diff)
Add meta-definitions for AST types
- The big change here is that all the definitions for syntax-node classes have been macro-ized, to that we can do light metaprogramming over them - The use of macros for this has big down-sides, but I'm not quite ready to do anything more heavy-weight right now - The macro-ized definitions can be included multiple times, to generate different declarations/code as needed - The first example of using this meta-programming facility is a new visitor system - The actual visitor base classes and the dispatch logic are all generated from the meta-files - There was only one visitor left in the code: the semantics checker, so that was ported to the new system. - All current test cases pass, so *of course* that means all is well.
Diffstat (limited to 'source/slang/stmt-defs.h')
-rw-r--r--source/slang/stmt-defs.h101
1 files changed, 101 insertions, 0 deletions
diff --git a/source/slang/stmt-defs.h b/source/slang/stmt-defs.h
new file mode 100644
index 000000000..9cc1978bd
--- /dev/null
+++ b/source/slang/stmt-defs.h
@@ -0,0 +1,101 @@
+// stmt-defs.h
+
+// Syntax class definitions for statements.
+
+ABSTRACT_SYNTAX_CLASS(ScopeStmt, StatementSyntaxNode)
+ SYNTAX_FIELD(RefPtr<ScopeDecl>, scopeDecl)
+END_SYNTAX_CLASS()
+
+SYNTAX_CLASS(BlockStatementSyntaxNode, ScopeStmt)
+ SYNTAX_FIELD(List<RefPtr<StatementSyntaxNode>>, Statements)
+END_SYNTAX_CLASS()
+
+SYNTAX_CLASS(UnparsedStmt, StatementSyntaxNode)
+ // The tokens that were contained between `{` and `}`
+ FIELD(List<Token>, tokens)
+END_SYNTAX_CLASS()
+
+SIMPLE_SYNTAX_CLASS(EmptyStatementSyntaxNode, StatementSyntaxNode)
+
+SIMPLE_SYNTAX_CLASS(DiscardStatementSyntaxNode, StatementSyntaxNode)
+
+SYNTAX_CLASS(VarDeclrStatementSyntaxNode, StatementSyntaxNode)
+ SYNTAX_FIELD(RefPtr<DeclBase>, decl)
+END_SYNTAX_CLASS()
+
+SYNTAX_CLASS(IfStatementSyntaxNode, StatementSyntaxNode)
+ SYNTAX_FIELD(RefPtr<ExpressionSyntaxNode>, Predicate)
+ SYNTAX_FIELD(RefPtr<StatementSyntaxNode>, PositiveStatement)
+ SYNTAX_FIELD(RefPtr<StatementSyntaxNode>, NegativeStatement)
+END_SYNTAX_CLASS()
+
+// A statement that can be escaped with a `break`
+ABSTRACT_SYNTAX_CLASS(BreakableStmt, ScopeStmt)
+END_SYNTAX_CLASS()
+
+SYNTAX_CLASS(SwitchStmt, BreakableStmt)
+ SYNTAX_FIELD(RefPtr<ExpressionSyntaxNode>, condition)
+ SYNTAX_FIELD(RefPtr<StatementSyntaxNode>, body)
+END_SYNTAX_CLASS()
+
+// A statement that is expected to appear lexically nested inside
+// some other construct, and thus needs to keep track of the
+// outer statement that it is associated with...
+ABSTRACT_SYNTAX_CLASS(ChildStmt, StatementSyntaxNode)
+ DECL_FIELD(StatementSyntaxNode*, parentStmt RAW(= nullptr))
+END_SYNTAX_CLASS()
+
+// a `case` or `default` statement inside a `switch`
+//
+// Note(tfoley): A correct AST for a C-like language would treat
+// these as a labelled statement, and so they would contain a
+// sub-statement. I'm leaving that out for now for simplicity.
+ABSTRACT_SYNTAX_CLASS(CaseStmtBase, ChildStmt)
+END_SYNTAX_CLASS()
+
+// a `case` statement inside a `switch`
+SYNTAX_CLASS(CaseStmt, CaseStmtBase)
+ SYNTAX_FIELD(RefPtr<ExpressionSyntaxNode>, expr)
+END_SYNTAX_CLASS()
+
+// a `default` statement inside a `switch`
+SIMPLE_SYNTAX_CLASS(DefaultStmt, CaseStmtBase)
+
+// A statement that represents a loop, and can thus be escaped with a `continue`
+ABSTRACT_SYNTAX_CLASS(LoopStmt, BreakableStmt)
+END_SYNTAX_CLASS()
+
+SYNTAX_CLASS(ForStatementSyntaxNode, LoopStmt)
+ SYNTAX_FIELD(RefPtr<StatementSyntaxNode>, InitialStatement)
+ SYNTAX_FIELD(RefPtr<ExpressionSyntaxNode>, SideEffectExpression)
+ SYNTAX_FIELD(RefPtr<ExpressionSyntaxNode>, PredicateExpression)
+ SYNTAX_FIELD(RefPtr<StatementSyntaxNode>, Statement)
+END_SYNTAX_CLASS()
+
+
+SYNTAX_CLASS(WhileStatementSyntaxNode, LoopStmt)
+ SYNTAX_FIELD(RefPtr<ExpressionSyntaxNode>, Predicate)
+ SYNTAX_FIELD(RefPtr<StatementSyntaxNode>, Statement)
+END_SYNTAX_CLASS()
+
+SYNTAX_CLASS(DoWhileStatementSyntaxNode, LoopStmt)
+ SYNTAX_FIELD(RefPtr<StatementSyntaxNode>, Statement)
+ SYNTAX_FIELD(RefPtr<ExpressionSyntaxNode>, Predicate)
+END_SYNTAX_CLASS()
+
+// The case of child statements that do control flow relative
+// to their parent statement.
+ABSTRACT_SYNTAX_CLASS(JumpStmt, ChildStmt)
+END_SYNTAX_CLASS()
+
+SIMPLE_SYNTAX_CLASS(BreakStatementSyntaxNode, JumpStmt)
+
+SIMPLE_SYNTAX_CLASS(ContinueStatementSyntaxNode, JumpStmt)
+
+SYNTAX_CLASS(ReturnStatementSyntaxNode, StatementSyntaxNode)
+ SYNTAX_FIELD(RefPtr<ExpressionSyntaxNode>, Expression)
+END_SYNTAX_CLASS()
+
+SYNTAX_CLASS(ExpressionStatementSyntaxNode, StatementSyntaxNode)
+ SYNTAX_FIELD(RefPtr<ExpressionSyntaxNode>, Expression)
+END_SYNTAX_CLASS()