From 9ba8ce30f8314a79169e6d9cfa12e5db7239693f Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Fri, 16 Jun 2017 09:09:09 -0700 Subject: Bug fix: handle unchecked operator application in emit logic When in rewriter mode, the emit logic will never see function applications inside function bodies, but it *will* see function application expressions at global scope, and some of these expressions might be unchecked. The challenge here is that even simple math operations now show up as function calls, so we need a bit of special-case logic to detect unchecked calls and then emit them using the syntax they were written with (e.g., use infix syntax if they were written as an infix expression). --- source/slang/emit.cpp | 126 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 88 insertions(+), 38 deletions(-) (limited to 'source/slang/emit.cpp') diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index a2a1e9e21..ef5df830f 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -448,6 +448,51 @@ static String getStringOrIdentifierTokenValue( } } +// Emit a call expression that doesn't involve any special cases, +// just an expression of the form `f(a0, a1, ...)` +static void emitSimpleCallExpr( + EmitContext* context, + RefPtr callExpr, + int outerPrec) +{ + bool needClose = MaybeEmitParens(context, outerPrec, kPrecedence_Postfix); + + auto funcExpr = callExpr->FunctionExpr; + if (auto funcDeclRefExpr = funcExpr.As()) + { + auto declRef = funcDeclRefExpr->declRef; + if (auto ctorDeclRef = declRef.As()) + { + // We really want to emit a reference to the type begin constructed + EmitType(context, callExpr->Type); + } + else + { + // default case: just emit the decl ref + EmitExpr(context, funcExpr); + } + } + else + { + // default case: just emit the expression + EmitPostfixExpr(context, funcExpr); + } + + Emit(context, "("); + int argCount = callExpr->Arguments.Count(); + for (int aa = 0; aa < argCount; ++aa) + { + if (aa != 0) Emit(context, ", "); + EmitExpr(context, callExpr->Arguments[aa]); + } + Emit(context, ")"); + + if (needClose) + { + Emit(context, ")"); + } +} + static void emitCallExpr( EmitContext* context, RefPtr callExpr, @@ -458,7 +503,47 @@ static void emitCallExpr( { auto funcDeclRef = funcDeclRefExpr->declRef; auto funcDecl = funcDeclRef.getDecl(); - if (auto intrinsicOpModifier = funcDecl->FindModifier()) + if(!funcDecl) + { + // This can occur when we are dealing with unchecked input syntax, + // because we are in "rewriter" mode. In this case we should go + // ahead and emit things in the form that they were written. + if( auto infixExpr = callExpr.As() ) + { + EmitBinExpr( + context, + outerPrec, + kPrecedence_Comma, + funcDeclRefExpr->name.Buffer(), + callExpr); + } + else if( auto prefixExpr = callExpr.As() ) + { + EmitUnaryExpr( + context, + outerPrec, + kPrecedence_Prefix, + funcDeclRefExpr->name.Buffer(), + "", + callExpr); + } + else if(auto postfixExpr = callExpr.As()) + { + EmitUnaryExpr( + context, + outerPrec, + kPrecedence_Postfix, + "", + funcDeclRefExpr->name.Buffer(), + callExpr); + } + else + { + emitSimpleCallExpr(context, callExpr, outerPrec); + } + return; + } + else if (auto intrinsicOpModifier = funcDecl->FindModifier()) { switch (intrinsicOpModifier->op) { @@ -641,42 +726,7 @@ static void emitCallExpr( } // Fall through to default handling... - - bool needClose = MaybeEmitParens(context, outerPrec, kPrecedence_Postfix); - - if (auto funcDeclRefExpr = funcExpr.As()) - { - auto declRef = funcDeclRefExpr->declRef; - if (auto ctorDeclRef = declRef.As()) - { - // We really want to emit a reference to the type begin constructed - EmitType(context, callExpr->Type); - } - else - { - // default case: just emit the decl ref - EmitExpr(context, funcExpr); - } - } - else - { - // default case: just emit the expression - EmitPostfixExpr(context, funcExpr); - } - - Emit(context, "("); - int argCount = callExpr->Arguments.Count(); - for (int aa = 0; aa < argCount; ++aa) - { - if (aa != 0) Emit(context, ", "); - EmitExpr(context, callExpr->Arguments[aa]); - } - Emit(context, ")"); - - if (needClose) - { - Emit(context, ")"); - } + emitSimpleCallExpr(context, callExpr, outerPrec); } static void EmitExprWithPrecedence(EmitContext* context, RefPtr expr, int outerPrec) @@ -761,7 +811,7 @@ static void EmitExprWithPrecedence(EmitContext* context, RefPtrVariable); + emitName(context, varExpr->name); } } else if (auto derefExpr = expr.As()) -- cgit v1.2.3