// buildBooleanUnaryExpression builds the CodeDOM for a native unary operator. func (db *domBuilder) buildBooleanUnaryExpression(node compilergraph.GraphNode, op string) codedom.Expression { boolType := db.scopegraph.TypeGraph().BoolTypeReference() childExpr := codedom.NominalUnwrapping(db.getExpression(node, parser.NodeUnaryExpressionChildExpr), boolType, node) return codedom.NominalWrapping( codedom.UnaryOperation(op, childExpr, node), db.scopegraph.TypeGraph().BoolType(), node) }
// buildExpression builds the CodeDOM for the given SRG node and returns it as an expression. Will // panic if the returned DOM type is not an expression. func (db *domBuilder) buildExpression(node compilergraph.GraphNode) codedom.Expression { switch node.Kind() { // Access Expressions. case parser.NodeMemberAccessExpression: fallthrough case parser.NodeNullableMemberAccessExpression: fallthrough case parser.NodeDynamicMemberAccessExpression: return db.buildMemberAccessExpression(node) case parser.NodeTypeIdentifierExpression: return db.buildIdentifierExpression(node) case parser.NodeGenericSpecifierExpression: return db.buildGenericSpecifierExpression(node) case parser.NodeCastExpression: return db.buildCastExpression(node) case parser.NodeStreamMemberAccessExpression: return db.buildStreamMemberAccessExpression(node) // Await Expression. case parser.NodeTypeAwaitExpression: return db.buildAwaitExpression(node) // Lambda Expressions. case parser.NodeTypeLambdaExpression: return db.buildLambdaExpression(node) // SML Expressions. case parser.NodeTypeSmlExpression: return db.buildSmlExpression(node) case parser.NodeTypeSmlText: return db.buildSmlText(node) // Flow Expressions. case parser.NodeTypeConditionalExpression: return db.buildConditionalExpression(node) case parser.NodeTypeLoopExpression: return db.buildLoopExpression(node) // Op Expressions. case parser.NodeRootTypeExpression: return db.buildRootTypeExpression(node) case parser.NodeFunctionCallExpression: return db.buildFunctionCall(node) case parser.NodeSliceExpression: return db.buildSliceExpression(node) case parser.NodeNullComparisonExpression: return db.buildNullComparisonExpression(node) case parser.NodeAssertNotNullExpression: return db.buildAssertNotNullExpression(node) case parser.NodeIsComparisonExpression: return db.buildIsComparisonExpression(node) case parser.NodeInCollectionExpression: return db.buildInCollectionExpression(node) case parser.NodeBitwiseNotExpression: return db.buildUnaryOperatorExpression(node, nil) case parser.NodeKeywordNotExpression: return db.buildUnaryOperatorExpression(node, func(expr codedom.Expression) codedom.Expression { boolType := db.scopegraph.TypeGraph().BoolTypeReference() childExpr := codedom.UnaryOperation("!", codedom.NominalUnwrapping(expr, boolType, node), node) return codedom.NominalWrapping( childExpr, db.scopegraph.TypeGraph().BoolType(), node) }) case parser.NodeDefineRangeExpression: fallthrough case parser.NodeBitwiseXorExpression: fallthrough case parser.NodeBitwiseOrExpression: fallthrough case parser.NodeBitwiseAndExpression: fallthrough case parser.NodeBitwiseShiftLeftExpression: fallthrough case parser.NodeBitwiseShiftRightExpression: fallthrough case parser.NodeBinaryAddExpression: fallthrough case parser.NodeBinarySubtractExpression: fallthrough case parser.NodeBinaryMultiplyExpression: fallthrough case parser.NodeBinaryDivideExpression: fallthrough case parser.NodeBinaryModuloExpression: return db.buildBinaryOperatorExpression(node, nil) case parser.NodeComparisonEqualsExpression: return db.buildBinaryOperatorExpression(node, nil) case parser.NodeComparisonNotEqualsExpression: return db.buildBinaryOperatorExpression(node, func(expr codedom.Expression) codedom.Expression { boolType := db.scopegraph.TypeGraph().BoolTypeReference() childExpr := codedom.UnaryOperation("!", codedom.NominalUnwrapping(expr, boolType, node), node) return codedom.NominalRefWrapping( childExpr, boolType.NominalDataType(), boolType, node) }) case parser.NodeComparisonLTEExpression: return db.buildBinaryOperatorExpression(node, func(expr codedom.Expression) codedom.Expression { intType := db.scopegraph.TypeGraph().IntTypeReference() boolType := db.scopegraph.TypeGraph().BoolTypeReference() childExpr := codedom.BinaryOperation(codedom.NominalUnwrapping(expr, intType, node), "<=", codedom.LiteralValue("0", node), node) return codedom.NominalRefWrapping( childExpr, boolType.NominalDataType(), boolType, node) }) case parser.NodeComparisonLTExpression: return db.buildBinaryOperatorExpression(node, func(expr codedom.Expression) codedom.Expression { intType := db.scopegraph.TypeGraph().IntTypeReference() boolType := db.scopegraph.TypeGraph().BoolTypeReference() childExpr := codedom.BinaryOperation(codedom.NominalUnwrapping(expr, intType, node), "<", codedom.LiteralValue("0", node), node) return codedom.NominalRefWrapping( childExpr, boolType.NominalDataType(), boolType, node) }) case parser.NodeComparisonGTEExpression: return db.buildBinaryOperatorExpression(node, func(expr codedom.Expression) codedom.Expression { intType := db.scopegraph.TypeGraph().IntTypeReference() boolType := db.scopegraph.TypeGraph().BoolTypeReference() childExpr := codedom.BinaryOperation(codedom.NominalUnwrapping(expr, intType, node), ">=", codedom.LiteralValue("0", node), node) return codedom.NominalRefWrapping( childExpr, boolType.NominalDataType(), boolType, node) }) case parser.NodeComparisonGTExpression: return db.buildBinaryOperatorExpression(node, func(expr codedom.Expression) codedom.Expression { intType := db.scopegraph.TypeGraph().IntTypeReference() boolType := db.scopegraph.TypeGraph().BoolTypeReference() childExpr := codedom.BinaryOperation(codedom.NominalUnwrapping(expr, intType, node), ">", codedom.LiteralValue("0", node), node) return codedom.NominalRefWrapping( childExpr, boolType.NominalDataType(), boolType, node) }) // Boolean operators. case parser.NodeBooleanAndExpression: return db.buildBooleanBinaryExpression(node, "&&") case parser.NodeBooleanOrExpression: return db.buildBooleanBinaryExpression(node, "||") case parser.NodeBooleanNotExpression: return db.buildBooleanUnaryExpression(node, "!") // Literals. case parser.NodeStructuralNewExpression: return db.buildStructuralNewExpression(node) case parser.NodeNumericLiteralExpression: return db.buildNumericLiteral(node) case parser.NodeBooleanLiteralExpression: return db.buildBooleanLiteral(node) case parser.NodeStringLiteralExpression: return db.buildStringLiteral(node) case parser.NodeNullLiteralExpression: return db.buildNullLiteral(node) case parser.NodeThisLiteralExpression: return db.buildThisLiteral(node) case parser.NodeValLiteralExpression: return db.buildValLiteral(node) case parser.NodeListExpression: return db.buildListExpression(node) case parser.NodeSliceLiteralExpression: return db.buildSliceLiteralExpression(node) case parser.NodeMappingLiteralExpression: return db.buildMappingLiteralExpression(node) case parser.NodeMapExpression: return db.buildMapExpression(node) case parser.NodeTypeTemplateString: return db.buildTemplateStringExpression(node) case parser.NodeTaggedTemplateLiteralString: return db.buildTaggedTemplateString(node) default: panic(fmt.Sprintf("Unknown SRG expression node: %s", node.Kind())) return nil } }
// buildNativeUnaryExpression builds the CodeDOM for a native unary operator. func (db *domBuilder) buildNativeUnaryExpression(node compilergraph.GraphNode, op string) codedom.Expression { childExpr := db.getExpression(node, parser.NodeUnaryExpressionChildExpr) return codedom.UnaryOperation(op, childExpr, node) }