diff --git a/src/frontend/meta/ast.nim b/src/frontend/meta/ast.nim index 8578e7f..9143c00 100644 --- a/src/frontend/meta/ast.nim +++ b/src/frontend/meta/ast.nim @@ -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})""" diff --git a/src/frontend/parser.nim b/src/frontend/parser.nim index 49a4fdf..c1a9a91 100644 --- a/src/frontend/parser.nim +++ b/src/frontend/parser.nim @@ -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