Fixed support for type declarations in the parser

This commit is contained in:
Mattia Giambirtone 2022-11-04 14:56:42 +01:00
parent 31a995b0d8
commit e09db61bc6
2 changed files with 36 additions and 13 deletions

View File

@ -273,7 +273,9 @@ type
name*: IdentExpr name*: IdentExpr
fields*: seq[tuple[name: IdentExpr, valueType: Expression, isPrivate: bool]] fields*: seq[tuple[name: IdentExpr, valueType: Expression, isPrivate: bool]]
defaults*: seq[Expression] defaults*: seq[Expression]
valueType*: Expression isEnum*: bool
isRef*: bool
parent*: IdentExpr
Pragma* = ref object of Expression Pragma* = ref object of Expression
name*: IdentExpr name*: IdentExpr
@ -646,7 +648,7 @@ proc newFunDecl*(name: IdentExpr, arguments: seq[tuple[name: IdentExpr, valueTyp
proc newTypeDecl*(name: IdentExpr, fields: seq[tuple[name: IdentExpr, valueType: Expression, isPrivate: bool]], proc newTypeDecl*(name: IdentExpr, fields: seq[tuple[name: IdentExpr, valueType: Expression, isPrivate: bool]],
defaults: seq[Expression], isPrivate: bool, token: Token, pragmas: seq[Pragma], defaults: seq[Expression], isPrivate: bool, token: Token, pragmas: seq[Pragma],
generics: seq[tuple[name: IdentExpr, cond: Expression]], valueType: Expression): TypeDecl = generics: seq[tuple[name: IdentExpr, cond: Expression]], parent: IdentExpr, isEnum: bool, isRef: bool): TypeDecl =
result = TypeDecl(kind: typeDecl) result = TypeDecl(kind: typeDecl)
result.name = name result.name = name
result.fields = fields result.fields = fields
@ -655,7 +657,9 @@ proc newTypeDecl*(name: IdentExpr, fields: seq[tuple[name: IdentExpr, valueType:
result.token = token result.token = token
result.pragmas = pragmas result.pragmas = pragmas
result.generics = generics result.generics = generics
result.valueType = valueType result.parent = parent
result.isEnum = isEnum
result.isRef = isRef
proc `$`*(self: ASTNode): string = proc `$`*(self: ASTNode): string =
@ -744,7 +748,7 @@ proc `$`*(self: ASTNode): string =
result &= &"""FunDecl(name={self.name}, body={self.body}, type={self.returnType}, arguments=[{self.arguments.join(", ")}], defaults=[{self.defaults.join(", ")}], generics=[{self.generics.join(", ")}], async={self.isAsync}, generator={self.isGenerator}, private={self.isPrivate}, pragmas={self.pragmas})""" result &= &"""FunDecl(name={self.name}, body={self.body}, type={self.returnType}, arguments=[{self.arguments.join(", ")}], defaults=[{self.defaults.join(", ")}], generics=[{self.generics.join(", ")}], async={self.isAsync}, generator={self.isGenerator}, private={self.isPrivate}, pragmas={self.pragmas})"""
of typeDecl: of typeDecl:
var self = TypeDecl(self) var self = TypeDecl(self)
result &= &"""TypeDecl(name={self.name}, fields={self.fields}, defaults={self.defaults}, private={self.isPrivate}, pragmas={self.pragmas}, generics={self.generics}, pragmas={self.pragmas}, type={self.valueType})""" result &= &"""TypeDecl(name={self.name}, fields={self.fields}, defaults={self.defaults}, private={self.isPrivate}, pragmas={self.pragmas}, generics={self.generics}, parent={self.parent}, ref={self.isRef}, enum={self.isEnum})"""
of lambdaExpr: of lambdaExpr:
var self = LambdaExpr(self) var self = LambdaExpr(self)
result &= &"""Lambda(body={self.body}, type={self.returnType}, arguments=[{self.arguments.join(", ")}], defaults=[{self.defaults.join(", ")}], generator={self.isGenerator}, async={self.isAsync}, pragmas={self.pragmas})""" result &= &"""Lambda(body={self.body}, type={self.returnType}, arguments=[{self.arguments.join(", ")}], defaults=[{self.defaults.join(", ")}], generator={self.isGenerator}, async={self.isAsync}, pragmas={self.pragmas})"""

View File

@ -1183,11 +1183,23 @@ proc typeDecl(self: Parser): TypeDecl =
var defaults: seq[Expression] = @[] var defaults: seq[Expression] = @[]
var generics: seq[tuple[name: IdentExpr, cond: Expression]] = @[] var generics: seq[tuple[name: IdentExpr, cond: Expression]] = @[]
var pragmas: seq[Pragma] = @[] var pragmas: seq[Pragma] = @[]
result = newTypeDecl(name, fields, defaults, isPrivate, token, pragmas, generics, nil) result = newTypeDecl(name, fields, defaults, isPrivate, token, pragmas, generics, nil, false, false)
if self.match(LeftBracket): if self.match(LeftBracket):
self.parseGenerics(result) self.parseGenerics(result)
self.expect("=", "expecting '=' after type name") self.expect("=", "expecting '=' after type name")
result.valueType = self.expression() case self.step().lexeme:
of "ref":
self.expect("object", "expecting 'object' after 'ref'")
result.isRef = true
of "enum":
result.isEnum = true
of "object":
discard # Default case
else:
self.error("invalid syntax")
if not result.isEnum and self.match("of"):
self.expect(Identifier, "expecting parent type name after 'of'")
result.parent = newIdentExpr(self.peek(-1))
self.expect(LeftBrace, "expecting '{' after type declaration") self.expect(LeftBrace, "expecting '{' after type declaration")
if self.match(TokenType.Pragma): if self.match(TokenType.Pragma):
for pragma in self.parsePragmas(): for pragma in self.parsePragmas():
@ -1199,13 +1211,20 @@ proc typeDecl(self: Parser): TypeDecl =
while not self.match(RightBrace) and not self.done(): while not self.match(RightBrace) and not self.done():
self.expect(Identifier, "expecting field name") self.expect(Identifier, "expecting field name")
argName = newIdentExpr(self.peek(-1), self.scopeDepth) argName = newIdentExpr(self.peek(-1), self.scopeDepth)
argPrivate = not self.match("*") if not result.isEnum:
self.expect(":", "expecting ':' after field name") argPrivate = not self.match("*")
argType = self.expression() self.expect(":", "expecting ':' after field name")
result.fields.add((argName, argType, argPrivate)) argType = self.expression()
if self.match("="): result.fields.add((argName, argType, argPrivate))
result.defaults.add(self.expression()) if self.match("="):
self.expect(";", "expecting semicolon after field declaration") result.defaults.add(self.expression())
else:
result.fields.add((argName, nil, false))
if not result.isEnum:
self.expect(";", "expecting semicolon after type field declaration")
else:
if not self.check(RightBrace):
self.expect(",", "expecting comma after enum field declaration")
result.pragmas = pragmas result.pragmas = pragmas