#include "slang-ast-synthesis.h" namespace Slang { Expr* ASTSynthesizer::emitBinaryExpr(UnownedStringSlice operatorToken, Expr* left, Expr* right) { auto infixExpr = m_builder->create(); infixExpr->functionExpr = emitVarExpr(m_namePool->getName(operatorToken)); ; infixExpr->arguments.add(left); infixExpr->arguments.add(right); return infixExpr; } Expr* ASTSynthesizer::emitPrefixExpr(UnownedStringSlice operatorToken, Expr* base) { auto prefixExpr = m_builder->create(); prefixExpr->functionExpr = emitVarExpr(m_namePool->getName(operatorToken)); ; prefixExpr->arguments.add(base); return prefixExpr; } Expr* ASTSynthesizer::emitPostfixExpr(UnownedStringSlice operatorToken, Expr* base) { auto postfixExpr = m_builder->create(); postfixExpr->functionExpr = emitVarExpr(m_namePool->getName(operatorToken)); ; postfixExpr->arguments.add(base); return postfixExpr; } ForStmt* ASTSynthesizer::emitFor(Expr* initVal, Expr* finalVal, VarDecl*& outIndexVar) { auto parentStmt = getCurrentScope().m_parentSeqStmt; auto seqStmt = m_builder->create(); auto scopeDecl = pushVarScope()->containerDecl; auto stmt = m_builder->create(); stmt->statement = seqStmt; stmt->scopeDecl = (ScopeDecl*)scopeDecl; auto declStmt = emitVarDeclStmt(nullptr, m_namePool->getName("S_synth_loop_index"), initVal); stmt->initialStatement = declStmt; outIndexVar = (VarDecl*)declStmt->decl; auto predicateExpr = emitBinaryExpr(UnownedStringSlice("<"), emitVarExpr(outIndexVar), finalVal); stmt->predicateExpression = predicateExpr; stmt->sideEffectExpression = emitPrefixExpr(UnownedStringSlice("++"), emitVarExpr(outIndexVar)); parentStmt->stmts.add(stmt); m_scopeStack.getLast().m_parentSeqStmt = seqStmt; return stmt; } Expr* ASTSynthesizer::emitThisExpr() { auto varExpr = m_builder->create(); varExpr->scope = getCurrentScope().m_scope; return varExpr; } Expr* ASTSynthesizer::emitVarExpr(Name* name) { auto scope = getCurrentScope(); SLANG_RELEASE_ASSERT(scope.m_scope); auto varExpr = m_builder->create(); varExpr->name = name; varExpr->scope = scope.m_scope; return varExpr; } Expr* ASTSynthesizer::emitVarExpr(VarDeclBase* varDecl) { auto varExpr = m_builder->create(); varExpr->declRef = makeDeclRef(varDecl); varExpr->type = varDecl->type.type; return varExpr; } Expr* ASTSynthesizer::emitVarExpr(VarDeclBase* var, Type* type) { auto expr = m_builder->create(); expr->declRef = makeDeclRef(var); expr->type.type = type; expr->type.isLeftValue = true; return expr; } Expr* ASTSynthesizer::emitVarExpr(DeclStmt* varStmt, Type* type) { auto expr = m_builder->create(); expr->declRef = makeDeclRef(as(varStmt->decl)); expr->type.type = type; expr->type.isLeftValue = true; return expr; } Expr* ASTSynthesizer::emitStaticTypeExpr(Type* type) { auto expr = m_builder->create(); expr->type.type = m_builder->getTypeType(type); expr->checked = true; return expr; } Expr* ASTSynthesizer::emitIntConst(int value) { auto expr = m_builder->create(); expr->type.type = m_builder->getIntType(); expr->value = value; return expr; } Expr* ASTSynthesizer::emitGetArrayLengthExpr(Expr* arrayExpr) { auto expr = m_builder->create(); expr->arrayExpr = arrayExpr; expr->type = m_builder->getIntType(); return expr; } Expr* ASTSynthesizer::emitMemberExpr(Expr* arrayExpr, Name* name) { auto rs = m_builder->create(); rs->baseExpression = arrayExpr; rs->name = name; return rs; } Expr* ASTSynthesizer::emitAssignExpr(Expr* left, Expr* right) { auto rs = m_builder->create(); rs->left = left; rs->right = right; return rs; } Expr* ASTSynthesizer::emitInvokeExpr(Expr* callee, List&& args) { auto rs = m_builder->create(); rs->functionExpr = callee; rs->arguments = _Move(args); return rs; } Expr* ASTSynthesizer::emitCtorInvokeExpr(Expr* callee, List&& args) { auto rs = m_builder->create(); rs->functionExpr = callee; rs->arguments = _Move(args); return rs; } Expr* ASTSynthesizer::emitGenericAppExpr(Expr* genericExpr, List&& args) { auto rs = m_builder->create(); rs->functionExpr = genericExpr; rs->arguments = _Move(args); return rs; } Expr* ASTSynthesizer::emitMemberExpr(Type* type, Name* name) { auto rs = m_builder->create(); auto typeExpr = m_builder->create(); auto typetype = m_builder->getOrCreate(type); typeExpr->type = typetype; rs->baseExpression = typeExpr; rs->name = name; return rs; } Expr* ASTSynthesizer::emitMemberExpr(QualType exprType, Expr* base, DeclRef declRef) { auto rs = m_builder->create(); rs->baseExpression = base; rs->declRef = declRef; rs->type = exprType; rs->checked = base->checked; return rs; } Expr* ASTSynthesizer::emitIndexExpr(Expr* base, Expr* index) { auto rs = m_builder->create(); rs->baseExpression = base; rs->indexExprs.add(index); return rs; } ExpressionStmt* ASTSynthesizer::emitExprStmt(Expr* expr) { auto rs = m_builder->create(); _addStmtToScope(rs); rs->expression = expr; return rs; } ReturnStmt* ASTSynthesizer::emitReturnStmt(Expr* expr) { auto rs = m_builder->create(); rs->expression = expr; _addStmtToScope(rs); return rs; } DeclStmt* ASTSynthesizer::emitVarDeclStmt(Type* type, Name* name, Expr* initVal) { auto scope = getCurrentScope(); SLANG_RELEASE_ASSERT(scope.m_parentSeqStmt); SLANG_RELEASE_ASSERT(scope.m_scope); SLANG_RELEASE_ASSERT(scope.m_scope->containerDecl); auto varDecl = m_builder->create(); varDecl->type.type = type; varDecl->nameAndLoc.name = name; varDecl->initExpr = initVal; scope.m_scope->containerDecl->addMember(varDecl); auto stmt = m_builder->create(); stmt->decl = varDecl; _addStmtToScope(stmt); return stmt; } } // namespace Slang