/*
* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
* This source file is part of the Cangjie project, licensed under Apache-2.0
* with Runtime Library Exception.
*
* See https://cangjie-lang.cn/pages/LICENSE for license information.
*/
// The Cangjie API is in Beta. For details on its capabilities and limitations, please refer to the README file.
package std.ast
import std.collection.ArrayList
public func parseExpr(input: Tokens): Expr {
/* Get node info from flatbuffer */
let node = unsafe {
try {
parse(input, {
p: CPointer<UInt8> => return CJ_AST_ParseExpr(match (MACRO_OBJECT.get()) {
case Some(ptr) => ptr
case None => CPointer<Unit>()
}, p, CPointer<Int64>())
})
} catch (e: Exception) {
throw ParseASTException("\n" + e.message + "parsing expr error.")
}
}
/* Get decl info from flatbuffer */
var astNode = generateExprAST(node.GetRootAsExpr())
return astNode
}
public func parseExprFragment(input: Tokens, startFrom!: Int64 = 0): (Expr, Int64) {
let (node, count) = unsafe {
try {
parseFragment(
input,
startFrom,
{
p: CPointer<UInt8>, sizeRef: CPointer<Int64> => return CJ_AST_ParseExpr(
match (MACRO_OBJECT.get()) {
case Some(ptr) => ptr
case None => CPointer<Unit>()
}, p, sizeRef)
}
)
} catch (e: Exception) {
throw ParseASTException("\n" + e.message + "parsing expr fragment error.")
}
}
var astNode = generateExprAST(node.GetRootAsExpr())
return (astNode, count)
}
func generateExprAST(exprNode: Option<NodeFormat_Expr>): Expr {
var expr = match (exprNode) {
case Some(v) => v
case None => throw ParseASTException()
}
var exprBase = match (expr.GetBase()) {
case Some(v) => v
case None => throw ParseASTException("Generate Expression failed")
}
var astKind: String = exprBase.GetAstKind()
var astNode = match (astKind) {
case "block" => createBlock(expr)
case "wildcard_expr" => createWildcardExpr(exprBase)
case "call_expr" => createCallExpr(expr)
case "paren_expr" => createParenExpr(expr)
case "member_access_expr" => createMemberAccess(expr)
case "optional_expr" => createOptionalExpr(expr)
case "optional_chain_expr" => createOptionalChainExpr(expr)
case "primitive_type_expr" => createPrimitiveTypeExpr(expr, exprBase)
case "return_expr" => createReturnExpr(expr)
case "lit_const_expr" => createLitConstExpr(expr, exprBase)
case "assign_expr" => createAssignExpr(expr)
case "unary_expr" => createUnaryExpr(expr)
case "while_expr" => createWhileExpr(expr)
case "ref_expr" => createRefExpr(expr)
case "binary_expr" => createBinaryExpr(expr)
case "inc_or_dec_expr" => createIncOrDecExpr(expr)
case "lambda_expr" => createLambdaExpr(expr)
case "trailing_closure_expr" => createTrailingClosureExpr(expr)
case "if_expr" => createIfExpr(expr)
case "quote_expr" => createQuoteExpr(expr, exprBase)
case "token_part" => createQuoteToken(expr)
case "try_expr" => createTryExpr(expr, exprBase)
case "jump_expr" => createJumpExpr(expr, exprBase)
case "subscript_expr" => createSubscriptExpr(expr)
case "range_expr" => createRangeExpr(expr)
case "tuple_lit_expr" => createTupleLiteral(expr)
case "array_lit_expr" => createArrayLiteral(expr)
case "for_in_expr" => createForInExpr(expr)
case "type_conv_expr" => createTypeConvExpr(expr)
case "synchronized_expr" => createSynchronizedExpr(expr)
case "spawn_expr" => createSpawnExpr(expr)
case "do_while_expr" => createDoWhileExpr(expr)
case "throw_expr" => createThrowExpr(expr)
case "perform_expr" => createPerformExpr(expr)
case "resume_expr" => createResumeExpr(expr)
case "is_expr" => createIsExpr(expr)
case "as_expr" => createAsExpr(expr)
case "array_expr" => createArrayExpr(expr)
case "match_expr" => createMatchExpr(expr, exprBase)
case "let_pattern_destructor" => createLetPatternExpr(expr, exprBase)
case "macro_expand_expr" => createMacroExpandExpr(expr)
case _ => throw ParseASTException("Unsupported parse the expr node: ${astKind}.\n")
}
addPositionInfo(astNode, exprBase)
return astNode
}
func createBlock(expr: NodeFormat_Expr): Expr {
return generateBlock(expr.GetExprAsBlock())
}
func generateBlock(blockOption: Option<NodeFormat_Block>): Block {
var block = match (blockOption) {
case Some(v) => v
case None => throw ParseASTException()
}
var lCurl: Token = Token()
if (isValidPosition(block.GetLeftCurlPos())) {
lCurl = Token(TokenKind.LCURL).addPosition(block.GetLeftCurlPos())
}
var body = block.GetBody()
var size = body.size
var nodes: ArrayList<Node> = ArrayList<Node>()
for (i in 0..size) {
nodes.add(generateNode(body[i]))
}
var rCurl: Token = Token()
if (isValidPosition(block.GetRightCurlPos())) {
rCurl = Token(TokenKind.RCURL).addPosition(block.GetRightCurlPos())
}
var unSafe = Token()
if (block.GetIsUnsafe()) {
unSafe = Token(TokenKind.UNSAFE).addPosition(block.GetUnsafePos())
}
return Block(lCurl, nodes, rCurl, unSafe)
}
func createBinaryExpr(expr: NodeFormat_Expr): Expr {
var biExpr = match (expr.GetExprAsBinaryExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var lexpr = generateExprAST(biExpr.GetLeftExpr())
var rexpr = generateExprAST(biExpr.GetRightExpr())
var op = Token(getTokenKind(biExpr.GetOperatorKind())).addPosition(biExpr.GetOperatorPos())
return BinaryExpr(lexpr, op, rexpr)
}
func createUnaryExpr(expr: NodeFormat_Expr): Expr {
var unExpr = match (expr.GetExprAsUnaryExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var childExpr = generateExprAST(unExpr.GetExpr())
var op = Token(getTokenKind(unExpr.GetOperatorKind())).addPosition(unExpr.GetOperatorPos())
return UnaryExpr(op, childExpr)
}
func createIsExpr(expr: NodeFormat_Expr): Expr {
var isExpr = match (expr.GetExprAsIsExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var exprNode = generateExprAST(isExpr.GetExpr())
var op = Token(TokenKind.IS).addPosition(isExpr.GetIsPos())
var ty = generateTypeAST(isExpr.GetIsType())
return IsExpr(exprNode, op, ty)
}
func createAsExpr(expr: NodeFormat_Expr): Expr {
var asExpr = match (expr.GetExprAsAsExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var exprNode = generateExprAST(asExpr.GetExpr())
var op = Token(TokenKind.AS).addPosition(asExpr.GetAsPos())
var ty = generateTypeAST(asExpr.GetAsType())
return AsExpr(exprNode, op, ty)
}
func createParenExpr(expr: NodeFormat_Expr): Expr {
var parenExpr = match (expr.GetExprAsParenExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var childExpr = generateExprAST(parenExpr.GetExpr())
var lParen = Token(TokenKind.LPAREN).addPosition(parenExpr.GetLeftParenPos())
var rParen = Token(TokenKind.RPAREN).addPosition(parenExpr.GetRightParenPos())
return ParenExpr(lParen, childExpr, rParen)
}
func createLitConstExpr(expr: NodeFormat_Expr, exprBase: NodeFormat_NodeBase): Expr {
var litExpr = match (expr.GetExprAsLitConstExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var litConstKind = TokenKindHelper.getLiteralConstKind(litExpr.GetLiteralConstKind())
if (litConstKind == TokenKind.STRING_LITERAL) {
// Determine the TokenKind Based on StringKind
litConstKind = TokenKindHelper.getStringKind(litExpr.GetStringKind())
if (litExpr.GetIsSingleQuote() && litConstKind == TokenKind.STRING_LITERAL) {
litConstKind = TokenKind.SINGLE_QUOTED_STRING_LITERAL
}
}
var literal = Token(litConstKind, litExpr.GetLiteral()).addPosition(exprBase.GetBegin())
if (litConstKind == TokenKind.UNIT_LITERAL) {
literal = Token(TokenKind.UNIT_LITERAL).addPosition(exprBase.GetBegin())
}
literal.delimiterNum = litExpr.GetDelimiterNum()
literal.isSingleQuote = litExpr.GetIsSingleQuote()
return LitConstExpr(literal)
}
func createCallExpr(expr: NodeFormat_Expr): Expr {
var callExpr = match (expr.GetExprAsCallExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var childExpr = generateExprAST(callExpr.GetBaseFunc())
var lParen = Token(TokenKind.LPAREN).addPosition(callExpr.GetLeftParenPos())
var args = ArrayList<Argument>()
for (arg in callExpr.GetArgs()) {
args.add(createArgument(arg))
}
var rParen = Token(TokenKind.RPAREN).addPosition(callExpr.GetRightParenPos())
return CallExpr(childExpr, lParen, args, rParen)
}
func createRefExpr(expr: NodeFormat_Expr): Expr {
return generateRefExpr(expr.GetExprAsRefExpr())
}
func generateRefExpr(ref: Option<NodeFormat_RefExpr>) {
var refExpr = match (ref) {
case Some(v) => v
case None => throw ParseASTException()
}
var identifier = match (refExpr.GetRef()) {
case Some(v) => match (v.GetIdentifier()) {
case "this" => Token(TokenKind.THIS).addPosition(v.GetIdentifierPos())
case "super" => Token(TokenKind.SUPER).addPosition(v.GetIdentifierPos())
case _ =>
if (refExpr.GetIsQuoteDollar()) {
Token(TokenKind.DOLLAR_IDENTIFIER, "$" + v.GetIdentifier()).addPosition(v.GetIdentifierPos())
} else {
Token(TokenKind.IDENTIFIER, v.GetIdentifier()).addPosition(v.GetIdentifierPos())
}
}
case None => throw ParseASTException("Can not get reference from CallExpr")
}
var lAngle = Token(TokenKind.LT).addPosition(refExpr.GetLeftAnglePos())
var typeArgs: ArrayList<TypeNode> = ArrayList<TypeNode>()
var typeArgument = refExpr.GetTypeArguments()
let commas = Tokens()
for (i in 0..typeArgument.size) {
typeArgs.add(generateTypeAST(typeArgument[i]))
match (typeArgument[i]?.GetBase()?.GetCommaPos()) {
case Some(position) where isValidPosition(position) => commas.append(
Token(TokenKind.COMMA).addPosition(position))
case _ => ()
}
}
var rAngle = Token(TokenKind.GT).addPosition(refExpr.GetRightAnglePos())
return RefExpr(identifier, lAngle, typeArgs, commas, rAngle)
}
func createReturnExpr(expr: NodeFormat_Expr): Expr {
var retExpr = match (expr.GetExprAsReturnExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var keyWord = Token(TokenKind.RETURN).addPosition(retExpr.GetReturnPos())
var exprNode = try {
Some<Expr>(generateExprAST(retExpr.GetExpr()))
} catch (e: ParseASTException) {
None<Expr>
}
return ReturnExpr(keyWord, exprNode)
}
func createThrowExpr(expr: NodeFormat_Expr): Expr {
var throwExpr = match (expr.GetExprAsThrowExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var keyWord = Token(TokenKind.THROW).addPosition(getNodeBeginPos(throwExpr.GetBase()))
var exprNode = generateExprAST(throwExpr.GetExpr())
return ThrowExpr(keyWord, exprNode)
}
func createPerformExpr(expr: NodeFormat_Expr): Expr {
var performExpr = match (expr.GetExprAsPerformExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var keyWord = Token(TokenKind.PERFORM).addPosition(getNodeBeginPos(performExpr.GetBase()))
var exprNode = generateExprAST(performExpr.GetExpr())
return PerformExpr(keyWord, exprNode)
}
func createResumeExpr(expr: NodeFormat_Expr): Expr {
var resumeExpr = match(expr.GetExprAsResumeExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var resume_ = Token(TokenKind.RESUME).addPosition(getNodeBeginPos(resumeExpr.GetBase()))
var with_ = None<Token>
var withExpr_ = None<Expr>
match(resumeExpr.GetWithExpr()) {
case Some(v) =>
with_ = Some(Token(TokenKind.WITH).addPosition(resumeExpr.GetWithPos()))
withExpr_ = Some(generateExprAST(resumeExpr.GetWithExpr()))
case None => ()
}
var throwing_ = None<Token>
var throwingExpr_ = None<Expr>
match(resumeExpr.GetThrowingExpr()) {
case Some(v) =>
throwing_ = Some(Token(TokenKind.THROWING).addPosition(resumeExpr.GetThrowingPos()))
throwingExpr_ = Some(generateExprAST(resumeExpr.GetThrowingExpr()))
case None => ()
}
return ResumeExpr(resume_, with_, withExpr_, throwing_, throwingExpr_)
}
func createAssignExpr(expr: NodeFormat_Expr): Expr {
var assignExpr = match (expr.GetExprAsAssignExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var lexpr = generateExprAST(assignExpr.GetLeftValue())
var rexpr = generateExprAST(assignExpr.GetRightExpr())
var op = Token(getTokenKind(assignExpr.GetAssignOp())).addPosition(assignExpr.GetAssignPos())
return AssignExpr(lexpr, op, rexpr)
}
func createMemberAccess(expr: NodeFormat_Expr): Expr {
var ma = match (expr.GetExprAsMemberAccess()) {
case Some(v) => v
case None => throw ParseASTException()
}
var postfixExpr = generateExprAST(ma.GetBaseExpr())
var dot = Token(TokenKind.DOT).addPosition(ma.GetDotPos())
var ident = Token(TokenKind.IDENTIFIER, ma.GetField()).addPosition(ma.GetFieldPos())
var lAngle = Token(TokenKind.LT).addPosition(ma.GetLeftAnglePos())
var typeArgs: ArrayList<TypeNode> = ArrayList<TypeNode>()
var typeArgument = ma.GetTypeArguments()
let commas = Tokens()
for (i in 0..typeArgument.size) {
typeArgs.add(generateTypeAST(typeArgument[i]))
match (typeArgument[i]?.GetBase()?.GetCommaPos()) {
case Some(position) where isValidPosition(position) => commas.append(
Token(TokenKind.COMMA).addPosition(position))
case _ => ()
}
}
var rAngle = Token(TokenKind.GT).addPosition(ma.GetRightAnglePos())
return MemberAccess(postfixExpr, dot, ident, lAngle, typeArgs, commas, rAngle)
}
func createOptionalExpr(expr: NodeFormat_Expr): Expr {
var oe = match (expr.GetExprAsOptionalExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var baseExpr = generateExprAST(oe.GetBaseExpr())
var quest = Token(TokenKind.QUEST).addPosition(oe.GetQuestPos())
return OptionalExpr(baseExpr, quest)
}
func createOptionalChainExpr(expr: NodeFormat_Expr): Expr {
var oce = match (expr.GetExprAsOptionalChainExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
return generateExprAST(oce.GetExpr())
}
func createIfExpr(expr: NodeFormat_Expr): Expr {
var ie = match (expr.GetExprAsIfExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var ifTk = Token(TokenKind.IF).addPosition(ie.GetIfPos())
var elseTk = Token()
if (ie.GetHasElse()) {
elseTk = Token(TokenKind.ELSE).addPosition(ie.GetElsePos())
}
var lParen = Token(TokenKind.LPAREN).addPosition(ie.GetLeftParenPos())
var cond = generateExprAST(ie.GetCondExpr())
var rParen = Token(TokenKind.RPAREN).addPosition(ie.GetRightParenPos())
var ifBlock = generateBlock(ie.GetBody())
var elseExpr = try {
Some<Expr>(generateExprAST(ie.GetElseBody()))
} catch (e: ParseASTException) {
None<Expr>
}
return IfExpr(ifTk, lParen, cond, rParen, ifBlock, elseTk, elseExpr)
}
func createLetPatternExpr(expr: NodeFormat_Expr, exprBase: NodeFormat_NodeBase) {
var letTk = Token(TokenKind.LET).addPosition(exprBase.GetBegin())
var letPattern = expr.GetExprAsLetPatternDestructor().getOrThrow()
var pattern = generatePatternAST(letPattern.GetPatterns()[0])
var backArrow = Token(TokenKind.BACKARROW).addPosition(letPattern.GetBackarrowPos())
var exprNode = generateExprAST(letPattern.GetInitializer())
let bitOrs = Tokens()
return LetPatternExpr(letTk, pattern, backArrow, exprNode)
}
func generateMatchCase(mc: Option<NodeFormat_MatchCase>) {
var matchCase = match (mc) {
case Some(v) => v
case None => throw ParseASTException()
}
var base = match (matchCase.GetBase()) {
case Some(v) => v
case None => throw ParseASTException()
}
var keyWord = Token(TokenKind.CASE).addPosition(base.GetBegin())
var patterns = ArrayList<Pattern>()
for (pattern in matchCase.GetPatterns()) {
patterns.add(generatePatternAST(pattern))
}
let bitOrs = Tokens()
for (bitOrPos in matchCase.GetBitOrPosVec()) {
bitOrs.append(Token(TokenKind.BITOR).addPosition(bitOrPos))
}
var whereTk = Token()
var patternGuard = try {
var pg = generateExprAST(matchCase.GetPatternguard())
whereTk = Token(TokenKind.WHERE).addPosition(matchCase.GetIfPos())
Some<Expr>(pg)
} catch (e: ParseASTException) {
None<Expr>
}
var arrow = Token(TokenKind.DOUBLE_ARROW).addPosition(matchCase.GetArrowPos())
var block = generateBlock(matchCase.GetExprOrDecls())
return MatchCase(keyWord, patterns, bitOrs, whereTk, patternGuard, arrow, block)
}
func generateMatchCaseOther(mco: Option<NodeFormat_MatchCaseOther>) {
var matchCaseOther = match (mco) {
case Some(v) => v
case None => throw ParseASTException()
}
var base = match (matchCaseOther.GetBase()) {
case Some(v) => v
case None => throw ParseASTException()
}
var keyWord = Token(TokenKind.CASE).addPosition(base.GetBegin())
// in matchCaseOther, a boolean-typed conditional expression is mandatory
var expr = Some<Expr>(generateExprAST(matchCaseOther.GetMatchExpr()))
var arrow = Token(TokenKind.DOUBLE_ARROW).addPosition(matchCaseOther.GetArrowPos())
var block = generateBlock(matchCaseOther.GetExprOrDecls())
return MatchCase(keyWord, expr, arrow, block)
}
func createMatchExpr(expr: NodeFormat_Expr, exprBase: NodeFormat_NodeBase): Expr {
var me = match (expr.GetExprAsMatchExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var keyWord: Token = Token(TokenKind.MATCH).addPosition(exprBase.GetBegin())
var lParen: Token = Token()
var rParen: Token = Token()
var selector: Option<Expr> = None<Expr>
// in pattern matching mode, () and selector are needed
if (me.GetMatchMode()) {
lParen = Token(TokenKind.LPAREN).addPosition(me.GetLeftParenPos())
rParen = Token(TokenKind.RPAREN).addPosition(me.GetRightParenPos())
selector = Some<Expr>(generateExprAST(me.GetSelector()))
}
var lCurl = Token(TokenKind.LCURL).addPosition(me.GetLeftCurlPos())
var matchcases: ArrayList<MatchCase> = ArrayList<MatchCase>()
// matchCases and matchCaseOthers cannot be not empty at the same time
for (mc in me.GetMatchCases()) {
matchcases.add(generateMatchCase(mc))
}
for (mco in me.GetMatchCaseOthers()) {
matchcases.add(generateMatchCaseOther(mco))
}
var rCurl = Token(TokenKind.RCURL).addPosition(me.GetRightCurlPos())
return MatchExpr(keyWord, lParen, selector, rParen, lCurl, matchcases, rCurl)
}
func createWhileExpr(expr: NodeFormat_Expr): Expr {
var whileExpr = match (expr.GetExprAsWhileExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var keyWord = Token(TokenKind.WHILE).addPosition(whileExpr.GetWhilePos())
var lParen = Token(TokenKind.LPAREN).addPosition(whileExpr.GetLeftParenPos())
var cond = generateExprAST(whileExpr.GetCondExpr())
var rParen = Token(TokenKind.RPAREN).addPosition(whileExpr.GetRightParenPos())
var block = generateBlock(whileExpr.GetBody())
return WhileExpr(keyWord, lParen, cond, rParen, block)
}
func createDoWhileExpr(expr: NodeFormat_Expr): Expr {
var doWhileExpr = match (expr.GetExprAsDoWhileExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var doTK: Token = Token(TokenKind.DO).addPosition(doWhileExpr.GetDoPos())
var block = generateBlock(doWhileExpr.GetBody())
var whileTK: Token = Token(TokenKind.WHILE).addPosition(doWhileExpr.GetWhilePos())
var lParen = Token(TokenKind.LPAREN).addPosition(doWhileExpr.GetLeftParenPos())
var cond = generateExprAST(doWhileExpr.GetCondExpr())
var rParen = Token(TokenKind.RPAREN).addPosition(doWhileExpr.GetRightParenPos())
return DoWhileExpr(doTK, block, whileTK, lParen, cond, rParen)
}
func createLambdaExpr(lambdaExpr: NodeFormat_LambdaExpr): LambdaExpr {
var funcBody = match (lambdaExpr.GetBody()) {
case Some(v) => v
case None => throw ParseASTException()
}
var funcParams: ArrayList<FuncParam> = generateFuncParams(funcBody)
var blockNode = match (funcBody.GetBody()) {
case Some(v) => v
case None => throw ParseASTException()
}
var base = match (lambdaExpr.GetBase()) {
case Some(v) => v
case None => throw ParseASTException()
}
var lCurl = Token(TokenKind.LCURL).addPosition(base.GetBegin())
var nodes: ArrayList<Node> = ArrayList<Node>()
var body = blockNode.GetBody()
for (i in 0..body.size) {
nodes.add(generateNode(body[i]))
}
var doubleArrow = Token()
if (isValidPosition(funcBody.GetArrowPos())) {
doubleArrow = Token(TokenKind.DOUBLE_ARROW).addPosition(funcBody.GetArrowPos())
}
var rCurl = Token(TokenKind.RCURL).addPosition(blockNode.GetRightCurlPos())
return LambdaExpr(lCurl, funcParams, doubleArrow, nodes, rCurl, lambdaExpr.GetMockSupported())
}
func createLambdaExpr(expr: NodeFormat_Expr): Expr {
var lambdaExpr = match (expr.GetExprAsLambdaExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
return createLambdaExpr(lambdaExpr)
}
func createSpawnExpr(expr: NodeFormat_Expr): Expr {
var spawnExpr = match (expr.GetExprAsSpawnExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var keyWord = Token(TokenKind.SPAWN).addPosition(spawnExpr.GetSpawnPos())
var lParen = Token()
var rParen = Token()
var context: Option<Expr> = None<Expr>
if (spawnExpr.GetHasArg()) {
lParen = Token(TokenKind.LPAREN).addPosition(spawnExpr.GetLeftParenPos())
context = try {
Some<Expr>(generateExprAST(spawnExpr.GetSpawnArgExpr()))
} catch (e: ParseASTException) {
None<Expr>
}
rParen = Token(TokenKind.RPAREN).addPosition(spawnExpr.GetRightParenPos())
}
var task = match (generateExprAST(spawnExpr.GetTaskExpr()) as LambdaExpr) {
case Some(v) => v
case None => throw ParseASTException("createSpawnExpr : get LambdaExpr")
}
return SpawnExpr(keyWord, lParen, context, rParen, task)
}
func createSynchronizedExpr(expr: NodeFormat_Expr): Expr {
var syncExpr = match (expr.GetExprAsSynchronizedExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var keyWord = Token(TokenKind.SYNCHRONIZED).addPosition(syncExpr.GetSyncPos())
var lParen = Token(TokenKind.LPAREN).addPosition(syncExpr.GetLeftParenPos())
var mutex = generateExprAST(syncExpr.GetMutexExpr())
var rParen = Token(TokenKind.RPAREN).addPosition(syncExpr.GetRightParenPos())
var block = generateBlock(syncExpr.GetBody())
return SynchronizedExpr(keyWord, lParen, mutex, rParen, block)
}
func createTrailingClosureExpr(expr: NodeFormat_Expr): Expr {
var trailExpr = match (expr.GetExprAsTrailingClosureExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var exprNode = generateExprAST(trailExpr.GetExpr())
var lambdaExpr = createLambdaExpr(trailExpr.GetLambda().getOrThrow())
return TrailingClosureExpr(exprNode, lambdaExpr)
}
func createTypeConvExpr(expr: NodeFormat_Expr): Expr {
var typeConvExpr = match (expr.GetExprAsTypeConvExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var ty = (generateTypeAST(typeConvExpr.GetType()) as PrimitiveType).getOrThrow()
var lParen = Token(TokenKind.LPAREN).addPosition(typeConvExpr.GetLeftParenPos())
var exprNode = generateExprAST(typeConvExpr.GetExpr())
var rParen = Token(TokenKind.RPAREN).addPosition(typeConvExpr.GetRightParenPos())
return TypeConvExpr(ty, lParen, exprNode, rParen)
}
func createForInExpr(expr: NodeFormat_Expr): Expr {
var forInExpr = match (expr.GetExprAsForInExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var forTk = Token(TokenKind.FOR).addPosition(getNodeBeginPos(forInExpr.GetBase()))
var lParen = Token(TokenKind.LPAREN).addPosition(forInExpr.GetLeftParenPos())
var pattern = generatePatternAST(forInExpr.GetPattern())
var inTk = Token(TokenKind.IN).addPosition(forInExpr.GetInPos())
var inExpr = generateExprAST(forInExpr.GetInExpr())
var whereTk = Token()
var patternGuard = try {
var pg = generateExprAST(forInExpr.GetPatternGuard())
whereTk = Token(TokenKind.WHERE).addPosition(forInExpr.GetIfPos())
Some<Expr>(pg)
} catch (e: ParseASTException) {
None<Expr>
}
var rParen = Token(TokenKind.RPAREN).addPosition(forInExpr.GetRightParenPos())
var block = generateBlock(forInExpr.GetBody())
return ForInExpr(forTk, lParen, pattern, inTk, inExpr, whereTk, patternGuard, rParen, block)
}
func createPrimitiveTypeExpr(expr: NodeFormat_Expr, exprBase: NodeFormat_NodeBase): Expr {
var primitiveTypeExpr = match (expr.GetExprAsPrimitiveTypeExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
let typeKind = primitiveTypeExpr.GetKind()
let beginPos = exprBase.GetBegin()
var kind = Token(TokenKindHelper.getPrimitiveTypeTokenKind(typeKind)).addPosition(beginPos)
return PrimitiveTypeExpr(kind)
}
func createArrayLiteral(expr: NodeFormat_Expr): Expr {
var arrayLiteral = match (expr.GetExprAsArrayLit()) {
case Some(v) => v
case None => throw ParseASTException()
}
let lSquare: Token = Token(TokenKind.LSQUARE).addPosition(arrayLiteral.GetLeftCurlPos())
let childs = arrayLiteral.GetChildren()
var elements = ArrayList<Expr>()
for (child in childs) {
elements.add(generateExprAST(child))
}
let rSquare: Token = Token(TokenKind.RSQUARE).addPosition(arrayLiteral.GetRightCurlPos())
var commas = Tokens()
for (pos in arrayLiteral.GetCommaPosVec()) {
commas.append(Token(COMMA).addPosition(pos))
}
return ArrayLiteral(lSquare, elements, commas, rSquare)
}
func createTupleLiteral(expr: NodeFormat_Expr): Expr {
var tupleLiteral = match (expr.GetExprAsTupleLit()) {
case Some(v) => v
case None => throw ParseASTException()
}
let lParen: Token = Token(TokenKind.LPAREN).addPosition(tupleLiteral.GetLeftParenPos())
let childs = tupleLiteral.GetChildren()
var elements = ArrayList<Expr>()
for (child in childs) {
elements.add(generateExprAST(child))
}
let rParen: Token = Token(TokenKind.RPAREN).addPosition(tupleLiteral.GetRightParenPos())
var commas = Tokens()
for (pos in tupleLiteral.GetCommaPosVec()) {
commas.append(Token(COMMA).addPosition(pos))
}
return TupleLiteral(lParen, elements, commas, rParen)
}
func createRangeExpr(expr: NodeFormat_Expr): Expr {
var rangeExpr = match (expr.GetExprAsRangeExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var start = try {
Some<Expr>(generateExprAST(rangeExpr.GetStartExpr()))
} catch (e: ParseASTException) {
None<Expr>
}
var kind = TokenKind.RANGEOP
if (rangeExpr.GetIsClosed()) {
kind = TokenKind.CLOSEDRANGEOP
}
var rangeOp = Token(kind).addPosition(rangeExpr.GetRangePos())
var stop = try {
Some<Expr>(generateExprAST(rangeExpr.GetStopExpr()))
} catch (e: ParseASTException) {
None<Expr>
}
var colon: Token = Token()
var step = try {
var stepExpr = generateExprAST(rangeExpr.GetStepExpr())
colon = Token(TokenKind.COLON).addPosition(rangeExpr.GetColonPos())
Some<Expr>(stepExpr)
} catch (e: ParseASTException) {
None<Expr>
}
return RangeExpr(start, rangeOp, stop, colon, step)
}
func createSubscriptExpr(expr: NodeFormat_Expr): Expr {
var subscriptExpr = match (expr.GetExprAsSubscriptExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var postfixExpr = generateExprAST(subscriptExpr.GetBaseExpr())
var lSquare: Token = Token(TokenKind.LSQUARE).addPosition(subscriptExpr.GetLeftSquarePos())
let childs = subscriptExpr.GetIndexExprs()
var elements = ArrayList<Expr>()
for (child in childs) {
elements.add(generateExprAST(child))
}
var rSquare: Token = Token(TokenKind.RSQUARE).addPosition(subscriptExpr.GetRightSquarePos())
return SubscriptExpr(postfixExpr, lSquare, elements, rSquare)
}
func createJumpExpr(expr: NodeFormat_Expr, exprBase: NodeFormat_NodeBase): Expr {
var jumpExpr = match (expr.GetExprAsJumpExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var tk = TokenKind.BREAK
if (!jumpExpr.GetIsBreak()) {
tk = TokenKind.CONTINUE
}
var kind = Tokens().append(Token(tk).addPosition(exprBase.GetBegin()))
return JumpExpr(kind)
}
func createIncOrDecExpr(expr: NodeFormat_Expr): Expr {
var incOrDecExpr = match (expr.GetExprAsIncOrDecExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var kind = Token(getTokenKind(incOrDecExpr.GetOperatorKind())).addPosition(incOrDecExpr.GetOperatorPos())
var exprNode = generateExprAST(incOrDecExpr.GetExpr())
return IncOrDecExpr(kind, exprNode)
}
func createTryExpr(expr: NodeFormat_Expr, exprBase: NodeFormat_NodeBase): Expr {
var tryExpr = match (expr.GetExprAsTryExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var tryToken: Token = Token(TokenKind.TRY).addPosition(exprBase.GetBegin())
var resourceSpec = ArrayList<VarDecl>()
let childs = tryExpr.GetResourceSpec()
for (child in childs) {
resourceSpec.add(createVarDeclNode(child))
}
var resourceSpecLParen = Token(TokenKind.LPAREN)
if (isValidPosition(tryExpr.GetResourceSpecLparenPos())) {
resourceSpecLParen = resourceSpecLParen.addPosition(tryExpr.GetResourceSpecLparenPos())
}
var resourceSpecRParen = Token(TokenKind.RPAREN)
if (isValidPosition(tryExpr.GetResourceSpecRparenPos())) {
resourceSpecRParen = resourceSpecRParen.addPosition(tryExpr.GetResourceSpecRparenPos())
}
var resourceSpecCommas = Tokens()
for (commaPos in tryExpr.GetResourceSpecCommaPosVec() where isValidPosition(commaPos)) {
resourceSpecCommas.append(Token(TokenKind.COMMA).addPosition(commaPos))
}
var tryBlock = generateBlock(tryExpr.GetTryBlock())
var catchPatterns = ArrayList<Pattern>()
var catches = Tokens()
for (pos in tryExpr.GetCatchPosVec() where isValidPosition(pos)) {
catches.append(Token(TokenKind.CATCH).addPosition(pos))
}
var catchLParens = Tokens()
for (pos in tryExpr.GetCatchLeftParenPosVec() where isValidPosition(pos)) {
catchLParens.append(Token(TokenKind.LPAREN).addPosition(pos))
}
var catchRParens = Tokens()
for (pos in tryExpr.GetCatchRightParenPosVec() where isValidPosition(pos)) {
catchRParens.append(Token(TokenKind.RPAREN).addPosition(pos))
}
for (cp in tryExpr.GetCatchPatterns()) {
catchPatterns.add(generatePatternAST(cp))
}
let catchBlocks = tryExpr.GetCatchBlocks()
var cbs: ArrayList<Block> = ArrayList<Block>()
for (cb in catchBlocks) {
cbs.add(generateBlock(cb))
}
var handlers = ArrayList<Handler>();
for (item in tryExpr.GetHandlers()) {
var fbHandler = match (item) {
case Some(v) => v
case None => throw ParseASTException("fbHandler is None")
}
var handle_ = Token(TokenKind.HANDLE).addPosition(fbHandler.GetHandlerPos())
var commandPattern = generatePatternAST(fbHandler.GetCommandPattern())
var handleBlock = generateBlock(fbHandler.GetHandleBlock())
var handler = Handler(handle_, commandPattern, handleBlock)
handlers.add(handler)
}
var finTk = Token()
var finallyBlock = try {
var fb = generateBlock(tryExpr.GetFinallyBlock())
finTk = Token(TokenKind.FINALLY).addPosition(tryExpr.GetFinallyPos())
Some<Block>(fb)
} catch (e: ParseASTException) {
None<Block>
}
return TryExpr(tryToken, resourceSpecLParen, resourceSpec, resourceSpecCommas, resourceSpecRParen, tryBlock, catches,
catchLParens, catchRParens, catchPatterns, cbs, finTk, finallyBlock, handlers)
}
func createQuoteExpr(expr: NodeFormat_Expr, exprBase: NodeFormat_NodeBase): Expr {
var quoteExpr = match (expr.GetExprAsQuoteExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
let lParen: Token = Token(TokenKind.LPAREN).addPosition(quoteExpr.GetLeftParenPos())
let childs = quoteExpr.GetExprs()
var elements = ArrayList<Expr>()
for (child in childs) {
elements.add(generateExprAST(child))
}
let rParen: Token = Token(TokenKind.RPAREN).addPosition(quoteExpr.GetRightParenPos())
var keyword: Token = Token(TokenKind.QUOTE).addPosition(exprBase.GetBegin())
return QuoteExpr(keyword, lParen, elements, rParen)
}
func createQuoteToken(expr: NodeFormat_Expr): Expr {
var tkp = match (expr.GetExprAsTokenPart()) {
case Some(v) => v
case None => throw ParseASTException()
}
var tks = Tokens()
for (tk in tkp.GetTokens()) {
match (tk) {
case Some(v) =>
let isSingle = v.GetIsSingleQuote()
var tokenKind = getTokenKind(v.GetKind())
if (tokenKind == STRING_LITERAL && isSingle == true) {
tokenKind = SINGLE_QUOTED_STRING_LITERAL
}
var token = Token(tokenKind, v.GetValue()).addPosition(v.GetPos())
token.delimiterNum = UInt16(v.GetDelimiterNum())
token.isSingleQuote = isSingle
if (v.GetHasEscape()) {
tks.append(Token(TokenKind.ILLEGAL, "\\", v.GetPos().fileId, v.GetPos().line, v.GetPos().column - 1))
}
tks.append(token)
case None => ()
}
}
return QuoteToken(tks)
}
func createWildcardExpr(exprBase: NodeFormat_NodeBase): Expr {
var keyword: Tokens = Tokens().append(Token(TokenKind.WILDCARD).addPosition(exprBase.GetBegin()))
return WildcardExpr(keyword)
}
func createArrayExpr(expr: NodeFormat_Expr): Expr {
var arrayExpr = match (expr.GetExprAsArrayExpr()) {
case Some(v) => v
case None => throw ParseASTException()
}
var ty = match (generateTypeAST(arrayExpr.GetType()) as VArrayType) {
case Some(v) => v
case None => throw ParseASTException()
}
var lParen: Token = Token(TokenKind.LPAREN).addPosition(arrayExpr.GetLeftParenPos())
var args: ArrayList<Argument> = ArrayList<Argument>()
for (arg in arrayExpr.GetArgs()) {
args.add(createArgument(arg))
}
var rParen: Token = Token(TokenKind.RPAREN).addPosition(arrayExpr.GetRightParenPos())
return VArrayExpr(ty, lParen, args, rParen)
}
func createMacroExpandExpr(expr: NodeFormat_Expr) {
var me = match (expr.GetExprAsMacroExpandExpr()) {
case Some(v) => v
case None => throw ParseASTException("Failed to get MacroExpand Node")
}
return match (createMacroExpand(me.GetInvocation()) as Expr) {
case Some(v) => v
case None => throw ParseASTException("Failed to create MacroExpandExpr Node")
}
}