/*
* 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 parseDecl(input: Tokens, astKind!: String = ""): Decl {
/* Get node info from flatbuffer */
var node = try {
match (astKind) {
case "PrimaryCtorDecl" => unsafe {
parse(
input,
{
p: CPointer<UInt8> => return CJ_AST_ParsePrimaryConstructor(match (MACRO_OBJECT.get()) {
case Some(ptr) => ptr
case None => CPointer<Unit>()
}, p)
}
)
}
case "PropMemberDecl" => unsafe {
parse(input, {
p: CPointer<UInt8> => return CJ_AST_ParsePropMemberDecl(match (MACRO_OBJECT.get()) {
case Some(ptr) => ptr
case None => CPointer<Unit>()
}, p)
})
}
case _ => unsafe { parse(input, {
p: CPointer<UInt8> => return CJ_AST_ParseDecl(match (MACRO_OBJECT.get()) {
case Some(ptr) => ptr
case None => CPointer<Unit>()
}, p, CPointer<Int64>())
}) }
}
} catch (e: Exception) {
throw ParseASTException("\n" + e.message + "parsing decl error.")
}
/* Get decl info from flatbuffer */
var astNode = generateDeclAST(node.GetRootAsDecl())
return astNode
}
public func parseDeclFragment(input: Tokens, startFrom!: Int64 = 0): (Decl, Int64) {
let (node, count) = unsafe {
try {
parseFragment(
input,
startFrom,
{
p: CPointer<UInt8>, sizeRef: CPointer<Int64> => return CJ_AST_ParseDecl(
match (MACRO_OBJECT.get()) {
case Some(ptr) => ptr
case None => CPointer<Unit>()
}, p, sizeRef)
}
)
} catch (e: Exception) {
throw ParseASTException("\n" + e.message + "parsing decl fragment error.")
}
}
var astNode = generateDeclAST(node.GetRootAsDecl())
return (astNode, count)
}
/**
* @throws ASTException if input tokens cannot be parsed to a FuncParam node.
*/
func parseFuncParam(input: Tokens): FuncParam {
var params = ArrayList<FuncParam>()
try {
let tokens = quote(foo($(input)){})
params = PrimaryCtorDecl(tokens).funcParams
} catch (_: ASTException) {
throw ASTException("Cannot construct the 'FuncParam' node.")
}
if (params.size == 0) {
throw ASTException("Cannot construct the 'FuncParam' node.")
}
params[0]
}
func generateDeclAST(declNode: Option<NodeFormat_Decl>): Decl {
var decl = match (declNode) {
case Some(v) => v
case None => throw ParseASTException()
}
var declBase = match (decl.GetBase()) {
case Some(v) => v
case None => throw ParseASTException()
}
var nodeBase = match (declBase.GetBase()) {
case Some(v) => v
case None => throw ParseASTException()
}
var astKind: String = nodeBase.GetAstKind()
var astNode = match (astKind) {
case "main_decl" => createMainDecl(decl, createDeclBase(Token(TokenKind.MAIN), declBase))
case "func_decl" => createFuncDecl(decl, declBase)
case "macro_decl" => createMacroDecl(decl, createDeclBase(Token(TokenKind.MACRO), declBase))
case "class_decl" => createClassDecl(decl, createDeclBase(Token(TokenKind.CLASS), declBase))
case "interface_decl" => createInterfaceDecl(decl, createDeclBase(Token(TokenKind.INTERFACE), declBase))
case "extend_decl" => createExtendDecl(decl, createDeclBase(Token(TokenKind.EXTEND), declBase))
case "enum_decl" => createEnumDecl(decl, createDeclBase(Token(TokenKind.ENUM), declBase))
case "struct_decl" => createStrucDecl(decl, createDeclBase(Token(TokenKind.STRUCT), declBase))
case "type_alias_decl" => createTypeAliasDecl(decl, declBase)
case "primary_ctor_decl" => createPrimaryCtorDecl(decl, createDeclBase(Token(), declBase))
case "var_decl" => createVarDecl(decl)
case "var_with_pattern_decl" => createVarWithPatternDecl(decl)
case "prop_decl" => createPropDecl(decl)
case "macro_expand_decl" => createMacroExpandDecl(decl)
case "func_param" => createFuncParam(decl)
case "macro_expand_param" => createMacroExpandParam(decl)
case _ => throw ParseASTException("Unsupported parse the decl node: ${astKind}.\n")
}
addPositionInfo(astNode, nodeBase)
return astNode
}
func createDeclBase(keyWord: Token, declBase: NodeFormat_DeclBase): Decl {
var annos: ArrayList<Annotation> = ArrayList<Annotation>()
for (anno in declBase.GetAnnotations()) {
annos.add(createAnnotation(anno))
}
var mods: ArrayList<Modifier> = ArrayList<Modifier>()
for (mod in declBase.GetModifiers()) {
mods.add(createModifier(mod))
}
var key = keyWord.addPosition(declBase.GetKeywordPos())
var indentifier = Token(TokenKind.IDENTIFIER, declBase.GetIdentifier()).addPosition(declBase.GetIdentifierPos())
var (param, constraint, constraintCommas, isGeneric) = generateGenericInfo(declBase.GetGeneric())
var genericParam: Option<GenericParam> = param
// Solve some special node
if (keyWord.kind == TokenKind.EXTEND) {
indentifier = Token()
} else if (keyWord.kind == TokenKind.FUNC) {
if (indentifier.value == "super") {
key = Token(TokenKind.SUPER).addPosition(declBase.GetKeywordPos())
}
if (indentifier.value == "init") {
key = Token(TokenKind.INIT).addPosition(declBase.GetKeywordPos())
}
}
if ((indentifier.value == "~init")) {
key = Token()
}
return Decl(annos, mods, key, indentifier, genericParam, constraint, constraintCommas, isGeneric)
}
func generateGenericInfo(generic: Option<NodeFormat_Generic>) {
var param: Option<GenericParam> = createGenericParam(generic)
var constraint = ArrayList<GenericConstraint>()
var isGeneric = false
let commas = Tokens()
match (generic) {
case Some(v) =>
var flag = true
isGeneric = true
for (cons in v.GetGenericConstraints()) {
constraint.add(createGenericConstraint(flag, cons))
match (cons?.GetCommaPos()) {
case Some(position) where isValidPosition(position) => commas.append(
Token(TokenKind.COMMA).addPosition(position))
case _ => ()
}
flag = false
}
case None => ()
}
return (param, constraint, commas, isGeneric)
}
func createClassDecl(decl: NodeFormat_Decl, declNode: Decl): ClassDecl {
var classDecl = match (decl.GetDeclAsClassDecl()) {
case Some(v) => v
case None => throw ParseASTException()
}
var up: Token = Token()
if (isValidPosition(classDecl.GetUpperBoundPos())) {
up = Token(TokenKind.UPPERBOUND).addPosition(classDecl.GetUpperBoundPos())
}
var superTypes: ArrayList<TypeNode> = ArrayList<TypeNode>()
let bitands = Tokens()
for (ty in classDecl.GetSuperTypes()) {
superTypes.add(generateTypeAST(ty))
match (ty?.GetBase()?.GetBitAndPos()) {
case Some(position) where isValidPosition(position) => bitands.append(
Token(TokenKind.BITAND).addPosition(position))
case _ => ()
}
}
var classbody = match (classDecl.GetBody()) {
case Some(v) => v
case None => throw ParseASTException()
}
var lcurl: Token = Token(TokenKind.LCURL).addPosition(classbody.GetLeftCurlPos())
var declList = ArrayList<Decl>()
var rcurl: Token = Token(TokenKind.RCURL).addPosition(classbody.GetRightCurlPos())
for (dl in classbody.GetDecls()) {
declList.add(generateDeclAST(dl))
}
return ClassDecl(declNode, up, superTypes, bitands, Body(lcurl, declList, rcurl))
}
func createStrucDecl(decl: NodeFormat_Decl, declNode: Decl): StructDecl {
var strucDecl = match (decl.GetDeclAsStructDecl()) {
case Some(v) => v
case None => throw ParseASTException()
}
var up: Token = Token()
if (isValidPosition(strucDecl.GetUpperBoundPos())) {
up = Token(TokenKind.UPPERBOUND).addPosition(strucDecl.GetUpperBoundPos())
}
var superTypes: ArrayList<TypeNode> = ArrayList<TypeNode>()
let bitands = Tokens()
for (ty in strucDecl.GetSuperTypes()) {
superTypes.add(generateTypeAST(ty))
match (ty?.GetBase()?.GetBitAndPos()) {
case Some(position) where isValidPosition(position) => bitands.append(
Token(TokenKind.BITAND).addPosition(position))
case _ => ()
}
}
var structbody = match (strucDecl.GetBody()) {
case Some(v) => v
case None => throw ParseASTException()
}
var lcurl: Token = Token(TokenKind.LCURL).addPosition(structbody.GetLeftCurlPos())
var declList = ArrayList<Decl>()
var rcurl: Token = Token(TokenKind.RCURL).addPosition(structbody.GetRightCurlPos())
for (dl in structbody.GetDecls()) {
declList.add(generateDeclAST(dl))
}
return StructDecl(declNode, up, superTypes, bitands, Body(lcurl, declList, rcurl))
}
func createInterfaceDecl(decl: NodeFormat_Decl, declNode: Decl): InterfaceDecl {
var interfaceDecl = match (decl.GetDeclAsInterfaceDecl()) {
case Some(v) => v
case None => throw ParseASTException()
}
var up: Token = Token()
if (isValidPosition(interfaceDecl.GetUpperBoundPos())) {
up = Token(TokenKind.UPPERBOUND).addPosition(interfaceDecl.GetUpperBoundPos())
}
var superTypes: ArrayList<TypeNode> = ArrayList<TypeNode>()
let bitands = Tokens()
for (ty in interfaceDecl.GetSuperTypes()) {
superTypes.add(generateTypeAST(ty))
match (ty?.GetBase()?.GetBitAndPos()) {
case Some(position) where isValidPosition(position) => bitands.append(
Token(TokenKind.BITAND).addPosition(position))
case _ => ()
}
}
var interfacebody = match (interfaceDecl.GetBody()) {
case Some(v) => v
case None => throw ParseASTException()
}
var lcurl: Token = Token(TokenKind.LCURL).addPosition(interfacebody.GetLeftCurlPos())
var declList = ArrayList<Decl>()
var rcurl: Token = Token(TokenKind.RCURL).addPosition(interfacebody.GetRightCurlPos())
for (dl in interfacebody.GetDecls()) {
declList.add(generateDeclAST(dl))
}
return InterfaceDecl(declNode, up, superTypes, bitands, Body(lcurl, declList, rcurl))
}
func createEnumDecl(decl: NodeFormat_Decl, declNode: Decl): EnumDecl {
var em = match (decl.GetDeclAsEnumDecl()) {
case Some(v) => v
case None => throw ParseASTException()
}
var up: Token = Token()
if (isValidPosition(em.GetUpperBoundPos())) {
up = Token(TokenKind.UPPERBOUND).addPosition(em.GetUpperBoundPos())
}
var superTypes: ArrayList<TypeNode> = ArrayList<TypeNode>()
let bitands = Tokens()
for (ty in em.GetSuperInterfaceTypes()) {
superTypes.add(generateTypeAST(ty))
match (ty?.GetBase()?.GetBitAndPos()) {
case Some(position) where isValidPosition(position) => bitands.append(
Token(TokenKind.BITAND).addPosition(position))
case _ => ()
}
}
var lcurl: Token = Token(TokenKind.LCURL).addPosition(em.GetLeftCurlPos())
var bitors: Tokens = Tokens()
for (pos in em.GetBitOrPosVec()) {
bitors.append(Token(TokenKind.BITOR).addPosition(pos))
}
var constructors = ArrayList<Constructor>()
for (cst in em.GetConstructors()) {
constructors.add(createConstructor(cst))
}
var members = ArrayList<Decl>()
for (mem in em.GetMembers()) {
members.add(generateDeclAST(mem))
}
var rcurl: Token = Token(TokenKind.RCURL).addPosition(em.GetRightCurlPos())
var ellipsis: Token = Token()
if (em.GetHasEllipsis()) {
ellipsis = Token(TokenKind.ELLIPSIS).addPosition(em.GetEllipsisPos())
}
return EnumDecl(declNode, up, superTypes, bitands, lcurl, bitors, constructors, members, rcurl, ellipsis)
}
func createExtendDecl(decl: NodeFormat_Decl, declNode: Decl): ExtendDecl {
var ed = match (decl.GetDeclAsExtendDecl()) {
case Some(v) => v
case None => throw ParseASTException()
}
var extendTy = match (ed.GetExtendedType()) {
case Some(v) => generateTypeAST(v)
case None => throw ParseASTException()
}
var up: Token = Token()
if (isValidPosition(ed.GetUpperBoundPos())) {
up = Token(TokenKind.UPPERBOUND).addPosition(ed.GetUpperBoundPos())
}
var superTypes: ArrayList<TypeNode> = ArrayList<TypeNode>()
let bitands = Tokens()
for (ty in ed.GetInterfaces()) {
superTypes.add(generateTypeAST(ty))
match (ty?.GetBase()?.GetBitAndPos()) {
case Some(position) where isValidPosition(position) => bitands.append(
Token(TokenKind.BITAND).addPosition(position))
case _ => ()
}
}
var lcurl: Token = Token(TokenKind.LCURL).addPosition(ed.GetLeftCurlPos())
var members = ArrayList<Decl>()
for (mem in ed.GetMembers()) {
members.add(generateDeclAST(mem))
}
var rcurl: Token = Token(TokenKind.RCURL).addPosition(ed.GetRightCurlPos())
return ExtendDecl(declNode, extendTy, up, superTypes, bitands, Body(lcurl, members, rcurl))
}
func createFuncDecl(decl: NodeFormat_Decl, declBase: NodeFormat_DeclBase): Decl {
var fd = match (decl.GetDeclAsFuncDecl()) {
case Some(v) => v
case None => throw ParseASTException()
}
let declNode = if (fd.GetIsGetter() || fd.GetIsSetter()) {
createDeclBase(Token(), declBase)
} else {
createDeclBase(Token(TokenKind.FUNC), declBase)
}
var funcDecl = generateCommonFuncDecl(fd, declNode)
// Deal with overload op.
var overloadOp = getOperaterKindOrIdentTokens(fd.GetOpKind(), fd.GetBase().getOrThrow().GetIdentifierPos(), Tokens())
funcDecl.overloadOp = overloadOp
return funcDecl
}
func createFuncParam(decl: NodeFormat_Decl): Decl {
return createFuncParam(decl.GetDeclAsFuncParam(), 0, 1)
}
func createMacroExpandParam(decl: NodeFormat_Decl): Decl {
let pm = match (decl.GetDeclAsMacroExpandParam()) {
case Some(v) => v
case None => throw ParseASTException()
}
return match (createMacroExpand(pm.GetInvocation(), isDecl: false, isFuncParam: true) as FuncParam) {
case Some(v) => v
case None => throw ParseASTException("Failed to create MacroExpandParam Node")
}
}
func createFuncParam(param: Option<NodeFormat_FuncParam>, index: Int64, length: Int64): FuncParam {
var pm = match (param) {
case Some(v) => v
case None => throw ParseASTException()
}
var astKind = pm.GetNodeBase().getOrThrow().GetAstKind()
if (astKind == "macro_expand_param") {
let annos: ArrayList<Annotation> = ArrayList<Annotation>()
let declBase = pm.GetBase().getOrThrow().GetBase().getOrThrow()
for (anno in declBase.GetAnnotations()) {
annos.add(createAnnotation(anno))
}
var mep = match (pm.GetMacroParamAsMacroExpandParam()) {
case Some(v) => v
case None => throw ParseASTException("Failed to get MacroExpandParam Node")
}
return match (createMacroExpand(mep.GetInvocation(), isDecl: false, isFuncParam: true) as FuncParam) {
case Some(v) => v.annotations.add(all: annos, at: 0)
v
case None => throw ParseASTException("Failed to create MacroExpandParam Node")
}
}
var varDecl = match (pm.GetBase()) {
case Some(v) => v
case None => throw ParseASTException()
}
var declBase = match (varDecl.GetBase()) {
case Some(v) => v
case None => throw ParseASTException()
}
var keyTk = Token()
if (pm.GetHasLetOrVar()) {
if (varDecl.GetIsVar()) {
keyTk = Token(TokenKind.VAR).addPosition(declBase.GetKeywordPos())
} else {
keyTk = Token(TokenKind.LET).addPosition(declBase.GetKeywordPos())
}
}
var declNode = createDeclBase(keyTk, declBase)
var comma = Token()
// funcParam in lambda expression may not have a type, so it is optional here.
var ty = try {
match (pm.GetBase()) {
case Some(v) => generateTypeAST(v.GetType())
case None => throw Exception()
}
} catch (e: Exception) {
TypeNode()
}
if (index != length - 1) {
comma = Token(TokenKind.COMMA).addPosition(pm.GetCommaPos())
}
var not = Token()
if (isValidPosition(pm.GetNotMarkPos())) {
not = Token(TokenKind.NOT).addPosition(pm.GetNotMarkPos())
}
var colon = Token()
if (isValidPosition(pm.GetColonPos())) {
colon = Token(TokenKind.COLON).addPosition(pm.GetColonPos())
}
var assign_ = Token()
var expr = try {
Some<Expr>(generateExprAST(pm.GetAssignment()))
} catch (e: ParseASTException) {
None<Expr>
}
if (let Some(v) <- expr) {
assign_ = Token(TokenKind.ASSIGN).addPosition(varDecl.GetAssignPos())
}
var isMemberParam = pm.GetIsMemberParam()
return FuncParam(declNode, not, colon, ty, assign_, expr, comma, isMemberParam)
}
func generateFuncParams(funcBody: NodeFormat_FuncBody): ArrayList<FuncParam> {
var params = match (funcBody.GetParamList()) {
case Some(v) => v.GetParams()
case None => throw ParseASTException()
}
var funcParams = ArrayList<FuncParam>()
for (i in 0..params.size) {
funcParams.add(createFuncParam(params[i], i, params.size))
}
return funcParams
}
func generateCommonFuncDecl(funcDecl: Option<NodeFormat_FuncDecl>, declNode: Decl) {
var fd = match (funcDecl) {
case Some(v) => v
case None => throw ParseASTException()
}
var (funcParams, colon, ty, block, lParen, rParen) = createFuncBody(fd.GetFuncBody())
var funcDeclNode = FuncDecl(declNode, lParen, funcParams, rParen, colon, ty, block)
var fb = match (fd.GetFuncBody()) {
case Some(v) => v
case None => NodeFormat_FuncBody(Array<UInt8>(0, repeat: 0), 0)
}
var (param, constraint, commaPos, isGeneric) = generateGenericInfo(fb.GetGeneric())
match (param) {
case Some(v) => funcDeclNode.genericParam = v
case None => ()
}
funcDeclNode.genericConstraint = constraint
funcDeclNode.constraintCommas = commaPos
funcDeclNode.isGenericDecl = isGeneric
funcDeclNode.isEnumConstruct = fd.GetIsEnumConstruct()
return funcDeclNode
}
func createFuncBody(funcBody: Option<NodeFormat_FuncBody>) {
var fb = match (funcBody) {
case Some(v) => v
case None => NodeFormat_FuncBody(Array<UInt8>(0, repeat: 0), 0)
}
// create function parameters
var funcParams: ArrayList<FuncParam> = generateFuncParams(fb)
var colon = Token()
var ty = try {
var retTy_ = generateTypeAST(fb.GetRetType())
colon = Token(TokenKind.COLON).addPosition(fb.GetColonPos())
Some<TypeNode>(retTy_)
} catch (e: ParseASTException) {
None<TypeNode>
}
// In a funcBody, the paramList and parentheses are mandatory, lambdaExpr is handled separately
var paramList = fb.GetParamList().getOrThrow()
var lParen = Token(TokenKind.LPAREN).addPosition(paramList.GetLeftParenPos())
var rParen = Token(TokenKind.RPAREN).addPosition(paramList.GetRightParenPos())
// create function block
return match (fb.GetBody()) {
case Some(blockNode) =>
var lCurl: Token = Token()
if (isValidPosition(blockNode.GetLeftCurlPos())) {
lCurl = Token(TokenKind.LCURL).addPosition(blockNode.GetLeftCurlPos())
}
var nodes: ArrayList<Node> = ArrayList<Node>()
for (i in 0..blockNode.GetBody().size) {
nodes.add(generateNode(blockNode.GetBody()[i]))
}
var rCurl: Token = Token()
if (isValidPosition(blockNode.GetRightCurlPos())) {
rCurl = Token(TokenKind.RCURL).addPosition(blockNode.GetRightCurlPos())
}
var unsafe_ = Token()
if (blockNode.GetIsUnsafe()) {
unsafe_ = Token(TokenKind.UNSAFE).addPosition(blockNode.GetUnsafePos())
}
var block = Block(lCurl, nodes, rCurl, unsafe_)
(funcParams, colon, ty, block, lParen, rParen)
case None => (funcParams, colon, ty, Block(), lParen, rParen)
}
}
func createMainDecl(decl: NodeFormat_Decl, declNode: Decl): MainDecl {
var md = match (decl.GetDeclAsMainDecl()) {
case Some(v) => v
case None => throw ParseASTException()
}
var (funcParams, colon, ty, block, lParen, rParen) = createFuncBody(md.GetFuncBody())
return MainDecl(declNode, lParen, funcParams, rParen, colon, ty, block)
}
func createMacroDecl(decl: NodeFormat_Decl, declNode: Decl): MacroDecl {
var mod = match (decl.GetDeclAsMacroDecl()) {
case Some(v) => v
case None => throw ParseASTException()
}
var (funcParams, colon, ty, block, lParen, rParen) = createFuncBody(mod.GetFuncBody())
return MacroDecl(declNode, lParen, funcParams, rParen, colon, ty, block)
}
func createPrimaryCtorDecl(decl: NodeFormat_Decl, declNode: Decl): PrimaryCtorDecl {
var pcd = match (decl.GetDeclAsPrimaryCtorDecl()) {
case Some(v) => v
case None => throw ParseASTException()
}
var (funcParams, _, _, block, lParen, rParen) = createFuncBody(pcd.GetFuncBody())
return PrimaryCtorDecl(declNode, lParen, funcParams, rParen, block)
}
func createVarDeclNode(decl: Option<NodeFormat_VarDecl>): VarDecl {
var varDecl = match (decl) {
case Some(v) => v
case None => throw ParseASTException()
}
var declBase = match (varDecl.GetBase()) {
case Some(v) => v
case None => throw ParseASTException()
}
var colon = Token()
var ty = try {
var declTy = generateTypeAST(varDecl.GetType())
colon = Token(TokenKind.COLON).addPosition(varDecl.GetColonPos())
Some<TypeNode>(declTy)
} catch (e: ParseASTException) {
None<TypeNode>
}
var assign = Token()
var expr = try {
var initExpr = generateExprAST(varDecl.GetInitializer())
assign = Token(TokenKind.ASSIGN).addPosition(varDecl.GetAssignPos())
Some<Expr>(initExpr)
} catch (e: ParseASTException) {
None<Expr>
}
var keyWord = Token()
if (varDecl.GetIsVar()) {
keyWord = Token(TokenKind.VAR).addPosition(declBase.GetKeywordPos())
} else if (varDecl.GetEmptyKeyword()) {
keyWord = Token()
} else if (declBase.GetIsConst()) {
keyWord = Token(TokenKind.CONST).addPosition(declBase.GetKeywordPos())
} else {
keyWord = Token(TokenKind.LET).addPosition(declBase.GetKeywordPos())
}
var vd = VarDecl(createDeclBase(keyWord, declBase), colon, ty, assign, expr)
vd.isEnumConstruct = varDecl.GetIsEnumConstruct()
return vd
}
func createVarDecl(decl: NodeFormat_Decl): Decl {
return createVarDeclNode(decl.GetDeclAsVarDecl())
}
func createVarWithPatternDecl(decl: NodeFormat_Decl): Decl {
var varWithPattern = match (decl.GetDeclAsVarWithPatternDecl()) {
case Some(v) => v
case None => throw ParseASTException()
}
var declBase = match (varWithPattern.GetBase()) {
case Some(v) => v
case None => throw ParseASTException()
}
var pattern = Some<Pattern>(generatePatternAST(varWithPattern.GetPattern()))
var colon = Token()
var ty = try {
var t = generateTypeAST(varWithPattern.GetType())
colon = Token(TokenKind.COLON).addPosition(varWithPattern.GetColonPos())
Some<TypeNode>(t)
} catch (e: ParseASTException) {
None<TypeNode>
}
var assign = Token()
var expr = try {
var initExpr = generateExprAST(varWithPattern.GetInitializer())
assign = Token(TokenKind.ASSIGN).addPosition(varWithPattern.GetAssignPos())
Some<Expr>(initExpr)
} catch (e: ParseASTException) {
None<Expr>
}
var keyWord = Token()
if (varWithPattern.GetIsVar()) {
keyWord = Token(TokenKind.VAR).addPosition(declBase.GetKeywordPos())
} else if (declBase.GetIsConst()) {
keyWord = Token(TokenKind.CONST).addPosition(declBase.GetKeywordPos())
} else {
keyWord = Token(TokenKind.LET).addPosition(declBase.GetKeywordPos())
}
return VarDecl(createDeclBase(keyWord, declBase), pattern, colon, ty, assign, expr)
}
func createPropDecl(decl: NodeFormat_Decl) {
var propDecl = match (decl.GetDeclAsPropDecl()) {
case Some(v) => v
case None => throw ParseASTException()
}
var varDecl = match (propDecl.GetBase()) {
case Some(v) => v
case None => throw ParseASTException()
}
var declBase = match (varDecl.GetBase()) {
case Some(v) => v
case None => throw ParseASTException()
}
var colon = Token(TokenKind.COLON).addPosition(propDecl.GetColonPos())
var ty = generateTypeAST(varDecl.GetType())
var lCurl = Token(TokenKind.LCURL).addPosition(propDecl.GetLeftCurlPos())
var getters = propDecl.GetGetters()
var getter = None<FuncDecl>
if (getters.size != 0) {
var db = match (getters[0]) {
case Some(v) => v.GetBase()
case None => throw ParseASTException()
}
getter = Some<FuncDecl>(generateCommonFuncDecl(getters[0], createDeclBase(Token(), db.getOrThrow())))
}
var setters = propDecl.GetSetters()
var setter = None<FuncDecl>
if (setters.size != 0) {
var db = match (setters[0]) {
case Some(v) => v.GetBase()
case None => throw ParseASTException()
}
setter = Some<FuncDecl>(generateCommonFuncDecl(setters[0], createDeclBase(Token(), db.getOrThrow())))
}
var rCurl = Token(TokenKind.RCURL).addPosition(propDecl.GetRightCurlPos())
return PropDecl(createDeclBase(Token(TokenKind.PROP).addPosition(declBase.GetKeywordPos()), declBase), colon, ty,
lCurl, getter, setter, rCurl)
}
func createTypeAliasDecl(decl: NodeFormat_Decl, declBase: NodeFormat_DeclBase) {
var typeAliasDecl = match (decl.GetDeclAsTypeAliasDecl()) {
case Some(v) => v
case None => throw ParseASTException()
}
var keyWord = Token(TokenKind.TYPE).addPosition(declBase.GetKeywordPos())
var assign: Token = Token(TokenKind.ASSIGN).addPosition(typeAliasDecl.GetAssignPos())
var ty = generateTypeAST(typeAliasDecl.GetType())
return TypeAliasDecl(createDeclBase(keyWord, declBase), assign, ty)
}
func createMacroExpandDecl(decl: NodeFormat_Decl) {
var annos: ArrayList<Annotation> = ArrayList<Annotation>()
var declBase = decl.GetBase().getOrThrow()
for (anno in declBase.GetAnnotations()) {
annos.add(createAnnotation(anno))
}
var me = match (decl.GetDeclAsMacroExpandDecl()) {
case Some(v) => v
case None => throw ParseASTException("Failed to get MacroExpand Node")
}
return match (createMacroExpand(me.GetInvocation(), isDecl: true) as Decl) {
case Some(v) => v.annotations.add(all: annos, at: 0)
v
case None => throw ParseASTException("Failed to create MacroExpandDecl Node")
}
}