Skip to content

Commit

Permalink
server/parser: Parse enum and enum members
Browse files Browse the repository at this point in the history
  • Loading branch information
SludgeGirl committed Jun 1, 2023
1 parent 04269a4 commit cd6bc73
Showing 1 changed file with 73 additions and 0 deletions.
73 changes: 73 additions & 0 deletions src/server/parser/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ import
ASTVisibility,
ASTParams,
ASTReturnType,
ASTEnum,
ASTEnumMember,
ASTTemplate,
ASTFunction,
ASTOperator,
Expand Down Expand Up @@ -1714,6 +1716,73 @@ export class Parser
return result
}

parseEnumDef(): Result<ASTNode, ParsingErrors>
{
const token = this.lexer.token.clone()
const match = this.match(TokenType.enumDef)
if (!match)
return Err('UnreachableState')

const ident = this.parseIdent()
if (!ident.isDefined())
return Err('InvalidTokenSequence')
if (ident.isErr() || ident.isInvalid())
return ident

const enumName = ident.val
// If the symbol's already in the table but is not a function symbol, that's an error
if (enumName.symbol && !enumName.symbol.type.mask(SymbolTypes.enum))
return Err('SymbolAlreadyDefined')
enumName.symbol = new MangroveSymbol(enumName.value, new SymbolType(SymbolTypes.enum | SymbolTypes.type))
this.symbolTable.insert(enumName.symbol)

const block = this.parseBlock({allowExtStmt: false, isEnum: true})
if (!block.isDefined())
return Err('InvalidTokenSequence')
if (block.isErr() || block.isInvalid())
return block
const astBlock = block.val as ASTBlock
const enumMembers = astBlock.statements
const valuesValid = enumMembers.every(value => value.valid)
if (enumMembers && !valuesValid)
this.symbolTable.pop(this)
return Ok(new ASTEnum(token, enumName, enumMembers as ASTEnumMember[]))
}

parseEnumMember(): Result<ASTEnumMember, ParsingErrors>
{
let value
const token = this.lexer.token
if (token.typeIsOneOf(TokenType.comma))
this.lexer.next()
this.skipWhite()
const ident = this.parseIdent()
if (!ident.isDefined())
return Err('InvalidTokenSequence')
if (ident.isErr() || ident.isInvalid())
return ident
// Parse the actual enum value
this.skipWhite()
if (token.typeIsOneOf(TokenType.assignOp))
{
this.lexer.next()
this.skipWhite()
value = this.parseInt()
}

if (value)
{
if (!value.isDefined)
return Err('InvalidTokenSequence')
if (value.isErr() || value.isInvalid())
return Err('InvalidAssignment')

return Ok(new ASTEnumMember(token, ident.val, value.val))
}

return Ok(new ASTEnumMember(token, ident.val))
}

parseFunctionDef(): Result<ASTNode, ParsingErrors>
{
const functionToken = this.lexer.token.clone()
Expand Down Expand Up @@ -1854,6 +1923,8 @@ export class Parser
const token = this.lexer.token
if (config.allowExtStmt && token.typeIsOneOf(TokenType.visibility))
return this.parseVisibility()
if (config.isEnum)
return this.parseEnumMember()
if (token.typeIsOneOf(TokenType.fromStmt))
return this.parseImportStmt()
if (token.typeIsOneOf(TokenType.ifStmt))
Expand All @@ -1862,6 +1933,8 @@ export class Parser
return this.parseForStmt()
if (token.typeIsOneOf(TokenType.whileStmt))
return this.parseWhileStmt()
if (token.typeIsOneOf(TokenType.enumDef))
return this.parseEnumDef()

const stmt = this.parseDefine()
if (stmt.isInvalid())
Expand Down

0 comments on commit cd6bc73

Please sign in to comment.