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
fields*: seq[tuple[name: IdentExpr, valueType: Expression, isPrivate: bool]]
defaults*: seq[Expression]
valueType*: Expression
isEnum*: bool
isRef*: bool
parent*: IdentExpr
Pragma* = ref object of Expression
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]],
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.name = name
result.fields = fields
@ -655,7 +657,9 @@ proc newTypeDecl*(name: IdentExpr, fields: seq[tuple[name: IdentExpr, valueType:
result.token = token
result.pragmas = pragmas
result.generics = generics
result.valueType = valueType
result.parent = parent
result.isEnum = isEnum
result.isRef = isRef
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})"""
of typeDecl:
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:
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})"""

View File

@ -1183,11 +1183,23 @@ proc typeDecl(self: Parser): TypeDecl =
var defaults: seq[Expression] = @[]
var generics: seq[tuple[name: IdentExpr, cond: Expression]] = @[]
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):
self.parseGenerics(result)
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")
if self.match(TokenType.Pragma):
for pragma in self.parsePragmas():
@ -1199,13 +1211,20 @@ proc typeDecl(self: Parser): TypeDecl =
while not self.match(RightBrace) and not self.done():
self.expect(Identifier, "expecting field name")
argName = newIdentExpr(self.peek(-1), self.scopeDepth)
argPrivate = not self.match("*")
self.expect(":", "expecting ':' after field name")
argType = self.expression()
result.fields.add((argName, argType, argPrivate))
if self.match("="):
result.defaults.add(self.expression())
self.expect(";", "expecting semicolon after field declaration")
if not result.isEnum:
argPrivate = not self.match("*")
self.expect(":", "expecting ':' after field name")
argType = self.expression()
result.fields.add((argName, argType, argPrivate))
if self.match("="):
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