From f69bc6cdb10aab2d1b202668cb7ecbcc0ddf33f2 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Fri, 7 Jul 2017 14:30:26 -0700 Subject: Fully parse function bodies, even in "rewriter" mode This is in anticipation of needing to have more complete knowledge to be able to handle user code that `import`s library functionality. The big picture of this change is just to remove the `UnparsedStmt` class that was used to hold the bodies of user functions as opaque token streams, and thus to let the full parser and compiler loose on that code. That is the easy part, of course, and the hard part is all the fixes that this requires in the rest of the compielr to make this even remotely work. Subsequent commit address a lot of other issues, so this particular commit mostly represents work-in-progress. One detail is that this change puts a conditional around nearly every diagnostic message in `check.cpp` to suppress thing when in rewriter mode. I have yet to check how that works out if there are errors in anything we actually need to understand for the purposes of generating reflection data. --- source/slang/expr-defs.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source/slang/expr-defs.h') diff --git a/source/slang/expr-defs.h b/source/slang/expr-defs.h index ca5bfacb8..5ca6629b9 100644 --- a/source/slang/expr-defs.h +++ b/source/slang/expr-defs.h @@ -96,6 +96,9 @@ SYNTAX_CLASS(TypeCastExpressionSyntaxNode, ExpressionSyntaxNode) SYNTAX_FIELD(RefPtr, Expression) END_SYNTAX_CLASS() +SYNTAX_CLASS(ImplicitCastExpr, TypeCastExpressionSyntaxNode) +END_SYNTAX_CLASS() + SIMPLE_SYNTAX_CLASS(SelectExpressionSyntaxNode, OperatorExpressionSyntaxNode) SIMPLE_SYNTAX_CLASS(GenericAppExpr, AppExprBase) @@ -112,3 +115,10 @@ SYNTAX_CLASS(AssignExpr, ExpressionSyntaxNode) SYNTAX_FIELD(RefPtr, right); END_SYNTAX_CLASS() +// Just an expression inside parentheses `(exp)` +// +// We keep this around explicitly to be sure we don't lose any structure +// when we do rewriter stuff. +SYNTAX_CLASS(ParenExpr, ExpressionSyntaxNode) + SYNTAX_FIELD(RefPtr, base); +END_SYNTAX_CLASS() -- cgit v1.2.3 From 6233f9b35f1901ca33c53ce37f9b1517e91e1d79 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Sat, 8 Jul 2017 17:04:31 -0700 Subject: Revise how hidden implicit casts are recognized. The old approach used an `isRewriter` flag in the emit logic, but I kind of need that flag to go away. Instead, I now how the semantic checking pass detect whether an implicitly-generated type cast is in rewriter code, and if so it uses the new `HiddenImplicitCastExpr` AST node. The emit logic then looks for that specific node and eliminates it. --- source/slang/check.cpp | 14 +++++++++++++- source/slang/emit.cpp | 17 +++++++---------- source/slang/expr-defs.h | 11 +++++++++++ source/slang/parser.cpp | 2 +- 4 files changed, 32 insertions(+), 12 deletions(-) (limited to 'source/slang/expr-defs.h') diff --git a/source/slang/check.cpp b/source/slang/check.cpp index f21f9480c..556f141c0 100644 --- a/source/slang/check.cpp +++ b/source/slang/check.cpp @@ -987,7 +987,19 @@ namespace Slang RefPtr toType, RefPtr fromExpr) { - auto castExpr = new ImplicitCastExpr(); + // In "rewrite" mode, we will generate a different syntax node + // to indicate that this type-cast was implicitly generated + // by the compiler, and shouldn't appear in the output code. + RefPtr castExpr; + if (isRewriteMode()) + { + castExpr = new HiddenImplicitCastExpr(); + } + else + { + castExpr = new ImplicitCastExpr(); + } + castExpr->Position = fromExpr->Position; castExpr->TargetType.type = toType; castExpr->Type = QualType(toType); diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index a1d95ca7e..a8c0083c1 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -2031,18 +2031,15 @@ struct EmitVisitor if(needClose) Emit(")"); } - void visitTypeCastExpressionSyntaxNode(TypeCastExpressionSyntaxNode* castExpr, ExprEmitArg const& arg) + void visitHiddenImplicitCastExpr(HiddenImplicitCastExpr* castExpr, ExprEmitArg const& arg) { - if (context->isRewrite) - { - if (dynamic_cast(castExpr)) - { - // This was an implicit cast, so don't try to output it - ExprVisitorWithArg::dispatch(castExpr->Expression, arg); - return; - } - } + // This was an implicit cast inserted in code parsed in "rewriter" mode, + // so we don't want to output it and change what the user's code looked like. + ExprVisitorWithArg::dispatch(castExpr->Expression, arg); + } + void visitTypeCastExpressionSyntaxNode(TypeCastExpressionSyntaxNode* castExpr, ExprEmitArg const& arg) + { bool needClose = false; switch(context->shared->target) { diff --git a/source/slang/expr-defs.h b/source/slang/expr-defs.h index 5ca6629b9..0dac324b9 100644 --- a/source/slang/expr-defs.h +++ b/source/slang/expr-defs.h @@ -91,14 +91,25 @@ SYNTAX_CLASS(DerefExpr, ExpressionSyntaxNode) SYNTAX_FIELD(RefPtr, base) END_SYNTAX_CLASS() +// Any operation that performs type-casting SYNTAX_CLASS(TypeCastExpressionSyntaxNode, ExpressionSyntaxNode) SYNTAX_FIELD(TypeExp, TargetType) SYNTAX_FIELD(RefPtr, Expression) END_SYNTAX_CLASS() +// An explicit type-cast that appear in the user's code with `(Type) expr` syntax +SYNTAX_CLASS(ExplicitCastExpr, TypeCastExpressionSyntaxNode) +END_SYNTAX_CLASS() + +// An implicit type-cast inserted during semantic checking SYNTAX_CLASS(ImplicitCastExpr, TypeCastExpressionSyntaxNode) END_SYNTAX_CLASS() +// An implicit type-cast that should also be hidden on output, +// because we don't want to mess with the user's code +SYNTAX_CLASS(HiddenImplicitCastExpr, ImplicitCastExpr) +END_SYNTAX_CLASS() + SIMPLE_SYNTAX_CLASS(SelectExpressionSyntaxNode, OperatorExpressionSyntaxNode) SIMPLE_SYNTAX_CLASS(GenericAppExpr, AppExprBase) diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp index 2056bf809..0efc8cd77 100644 --- a/source/slang/parser.cpp +++ b/source/slang/parser.cpp @@ -3092,7 +3092,7 @@ namespace Slang if (peekTypeName(parser) && parser->LookAheadToken(TokenType::RParent, 1)) { - RefPtr tcexpr = new TypeCastExpressionSyntaxNode(); + RefPtr tcexpr = new ExplicitCastExpr(); parser->FillPosition(tcexpr.Ptr()); tcexpr->TargetType = parser->ParseTypeExp(); parser->ReadToken(TokenType::RParent); -- cgit v1.2.3