struct -> class
This commit is contained in:
111
parser.v
111
parser.v
@@ -26,7 +26,7 @@ fn (p Parser) get_precedence(tok_type TokenType) Precedence {
|
||||
|
||||
// ------------------------------------------- Symbol Table
|
||||
|
||||
type SymbolInfo = VarSymbolInfo | FuncSymbolInfo | StructTypeSymbolInfo
|
||||
type SymbolInfo = VarSymbolInfo | FuncSymbolInfo | ClassSymbolInfo
|
||||
|
||||
struct VarSymbolInfo {
|
||||
type string
|
||||
@@ -37,7 +37,7 @@ struct FuncSymbolInfo {
|
||||
block Block
|
||||
}
|
||||
|
||||
struct StructTypeSymbolInfo {
|
||||
struct ClassSymbolInfo {
|
||||
name string
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ struct SymbolTable {
|
||||
mut:
|
||||
variable_scopes []map[string]VarSymbolInfo
|
||||
functions map[string]FuncSymbolInfo
|
||||
structs map[string]StructTypeSymbolInfo
|
||||
structs map[string]ClassSymbolInfo
|
||||
}
|
||||
|
||||
fn (mut s SymbolTable) define_var(name string, typ string) {
|
||||
@@ -90,11 +90,11 @@ fn (mut s SymbolTable) lookup_func(name string) ?FuncSymbolInfo {
|
||||
return none
|
||||
}
|
||||
|
||||
fn (mut s SymbolTable) define_struct_type(name string) {
|
||||
s.structs[name] = StructTypeSymbolInfo{name: name}
|
||||
fn (mut s SymbolTable) define_class(name string) {
|
||||
s.structs[name] = ClassSymbolInfo{name: name}
|
||||
}
|
||||
|
||||
fn (mut s SymbolTable) lookup_struct_type(name string) ?StructTypeSymbolInfo {
|
||||
fn (mut s SymbolTable) lookup_class(name string) ?ClassSymbolInfo {
|
||||
if name in s.structs {
|
||||
return s.structs[name]
|
||||
}
|
||||
@@ -108,7 +108,7 @@ fn (mut s SymbolTable) is_in_global_scope() bool {
|
||||
|
||||
// ------------------------------------------- Expressions
|
||||
|
||||
type Expr = VoidExpr | UnaryExpr | BinaryExpr | IntegerLiteral | RealLiteral | BoolLiteral | Variable | TypeExpr | Function | TypeCast | ParenExpr | PrintExpr | FnCall | StructMember | StructInstantiation
|
||||
type Expr = VoidExpr | UnaryExpr | BinaryExpr | IntegerLiteral | RealLiteral | BoolLiteral | Variable | TypeExpr | Function | TypeCast | ParenExpr | PrintExpr | FnCall | ClassMember | ClassInstantiation
|
||||
|
||||
struct VoidExpr {}
|
||||
|
||||
@@ -143,12 +143,12 @@ struct TypeExpr {
|
||||
name string
|
||||
}
|
||||
|
||||
struct StructMember {
|
||||
struct ClassMember {
|
||||
name string
|
||||
type string
|
||||
}
|
||||
|
||||
struct StructInstantiation {
|
||||
struct ClassInstantiation {
|
||||
name string
|
||||
member_values []Expr
|
||||
}
|
||||
@@ -178,7 +178,7 @@ struct FnCall {
|
||||
|
||||
// ------------------------------------------- Statements
|
||||
|
||||
type Stmt = VarDecl | ExprStmt | ReturnStmt | Block | FuncDecl | Param | StructDecl
|
||||
type Stmt = VarDecl | ExprStmt | ReturnStmt | Block | FuncDecl | Param | ClassDecl
|
||||
|
||||
struct VarDecl {
|
||||
name string
|
||||
@@ -194,9 +194,9 @@ struct FuncDecl {
|
||||
block Block
|
||||
}
|
||||
|
||||
struct StructDecl {
|
||||
struct ClassDecl {
|
||||
name string
|
||||
members []StructMember
|
||||
members []ClassMember
|
||||
}
|
||||
|
||||
struct ExprStmt {
|
||||
@@ -245,6 +245,11 @@ fn (mut p Parser) expect(type TokenType) {
|
||||
p.next()
|
||||
}
|
||||
|
||||
|
||||
fn (mut p Parser) expect_ident_is_class(ident string) {
|
||||
if !p.is_ident_class(ident) {panic("Expected type or class type but got identifier")}
|
||||
}
|
||||
|
||||
// ------------------------------------------- Debug
|
||||
|
||||
fn (mut p Parser) dump_token() {
|
||||
@@ -299,15 +304,15 @@ fn (mut p Parser) parse_expr(prec Precedence) Expr {
|
||||
}
|
||||
|
||||
fn (mut p Parser) parse_ident(ident string) Expr {
|
||||
if p.symbols.lookup_struct_type(ident) != none {
|
||||
if p.symbols.lookup_class(ident) != none {
|
||||
return match p.peek().type {
|
||||
.lbracket {p.parse_struct_inst(ident)}
|
||||
.lbracket {p.parse_class_inst(ident)}
|
||||
else {p.parse_type('struct ${ident}')}
|
||||
}
|
||||
}
|
||||
|
||||
if p.inside_struct {
|
||||
return p.parse_struct_member(ident)
|
||||
return p.parse_class_member(ident)
|
||||
}
|
||||
|
||||
return match p.peek().type {
|
||||
@@ -317,19 +322,25 @@ fn (mut p Parser) parse_ident(ident string) Expr {
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut p Parser) parse_struct_member(name string) StructMember {
|
||||
fn (mut p Parser) parse_class_member(name string) ClassMember {
|
||||
p.expect(.identifier)
|
||||
if p.peek().type != .type {
|
||||
dump(p.peek())
|
||||
parse_error("Expected type after struct member ${name} in declaration, got ${p.peek().type}")
|
||||
|
||||
type_tok := p.peek()
|
||||
type_name := match type_tok.type {
|
||||
.type {type_tok.text}
|
||||
.identifier {
|
||||
p.expect_ident_is_class(type_tok.text)
|
||||
'struct ${type_tok.text}'
|
||||
}
|
||||
else{parse_error("Expected type after class member ${name} in declaration, got ${p.peek().type}")}
|
||||
}
|
||||
type := p.peek().text
|
||||
p.expect(.type)
|
||||
|
||||
p.next()
|
||||
p.expect(.semicolon)
|
||||
return StructMember{name: name, type: type}
|
||||
return ClassMember{name: name, type: type_name}
|
||||
}
|
||||
|
||||
fn (mut p Parser) parse_struct_inst(name string) StructInstantiation {
|
||||
fn (mut p Parser) parse_class_inst(name string) ClassInstantiation {
|
||||
p.expect(.lbracket)
|
||||
mut member_values := []Expr{}
|
||||
|
||||
@@ -344,7 +355,7 @@ fn (mut p Parser) parse_struct_inst(name string) StructInstantiation {
|
||||
}
|
||||
}
|
||||
p.expect(.rbracket)
|
||||
return StructInstantiation{name: name, member_values: member_values}
|
||||
return ClassInstantiation{name: name, member_values: member_values}
|
||||
}
|
||||
|
||||
fn (mut p Parser) parse_call(name string) FnCall {
|
||||
@@ -415,6 +426,10 @@ fn (mut p Parser) check_binary_expr_types(expr BinaryExpr) {
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut p Parser) is_ident_class(ident string) bool {
|
||||
return p.symbols.lookup_class(ident) != none
|
||||
}
|
||||
|
||||
fn (mut p Parser) get_expr_type(expr Expr) string {
|
||||
return match expr {
|
||||
ParenExpr {p.get_expr_type(expr.expr)}
|
||||
@@ -422,6 +437,7 @@ fn (mut p Parser) get_expr_type(expr Expr) string {
|
||||
RealLiteral {'real'}
|
||||
BoolLiteral {'bool'}
|
||||
VoidExpr {'void'}
|
||||
TypeExpr {expr.name}
|
||||
BinaryExpr {
|
||||
p.check_binary_expr_types(expr)
|
||||
left_t := p.get_expr_type(expr.left)
|
||||
@@ -443,7 +459,7 @@ fn (mut p Parser) get_expr_type(expr Expr) string {
|
||||
fninfo := p.symbols.lookup_func(expr.name) or {parse_error("Tried to call undefined function ${expr.name}")}
|
||||
fninfo.type
|
||||
}
|
||||
StructInstantiation {expr.name}
|
||||
ClassInstantiation {expr.name}
|
||||
else {"Tried getting type of unexpected Expr"}
|
||||
}
|
||||
}
|
||||
@@ -477,11 +493,11 @@ fn (mut p Parser) get_return_stmts_recursive(block Block) []ReturnStmt {
|
||||
fn (mut p Parser) parse_statement() Stmt {
|
||||
match p.peek().type {
|
||||
.kw_let {return p.parse_var_decl(false)}
|
||||
.kw_const {return p.parse_var_decl(true)}
|
||||
.kw_const {return p.parse_var_decl(true)}
|
||||
.kw_return {return p.parse_return_stmt()}
|
||||
.kw_fn {return p.parse_func_decl()}
|
||||
.lbracket {return p.parse_block(false)}
|
||||
.kw_struct {return p.parse_struct()}
|
||||
.kw_class {return p.parse_class()}
|
||||
else {return p.parse_expr_stmt()}
|
||||
}
|
||||
}
|
||||
@@ -498,9 +514,7 @@ fn (mut p Parser) parse_var_decl(is_const bool) VarDecl {
|
||||
type_name := match type_tok.type {
|
||||
.type {type_tok.text}
|
||||
.identifier {
|
||||
if p.symbols.lookup_struct_type(type_tok.text) == none {
|
||||
parse_error("Expected variable type after name when declaring ${name_tok.text}")
|
||||
}
|
||||
p.expect_ident_is_class(type_tok.text)
|
||||
'struct ${type_tok.text}'
|
||||
}
|
||||
else{parse_error("Expected variable type after name when declaring ${name_tok.text}")}
|
||||
@@ -548,8 +562,18 @@ fn (mut p Parser) parse_func_decl() FuncDecl {
|
||||
for {
|
||||
if p.peek().type != .identifier {parse_error("Invalid syntax to declare function arguments! use f(myint int, myreal real)")}
|
||||
p_name := p.next().text
|
||||
if p.peek().type != .type {parse_error("Invalid syntax to declare function arguments! use f(myint int, myreal real)")}
|
||||
p_type := p.next().text
|
||||
//if p.peek().type != .type {parse_error("Invalid syntax to declare function arguments! use f(myint int, myreal real)")}
|
||||
|
||||
type_tok := p.peek()
|
||||
p_type := match type_tok.type {
|
||||
.type {type_tok.text}
|
||||
.identifier {
|
||||
p.expect_ident_is_class(type_tok.text)
|
||||
'struct ${type_tok.text}'
|
||||
}
|
||||
else{parse_error("Expected argument type after name when declaring ${p_name}")}
|
||||
}
|
||||
p.next()
|
||||
params << Param{p_name, p_type}
|
||||
p.symbols.define_var(p_name, p_type)
|
||||
|
||||
@@ -566,8 +590,13 @@ fn (mut p Parser) parse_func_decl() FuncDecl {
|
||||
p.dump_token()
|
||||
|
||||
type_tok := p.next()
|
||||
if type_tok.type != .type {
|
||||
parse_error("Expected function return type after name when declaring ${name_tok.text}")
|
||||
ret_type := match type_tok.type {
|
||||
.type {type_tok.text}
|
||||
.identifier {
|
||||
p.expect_ident_is_class(type_tok.text)
|
||||
'struct ${type_tok.text}'
|
||||
}
|
||||
else{parse_error("Expected function return type after name when declaring ${name_tok.text}")}
|
||||
}
|
||||
|
||||
block := p.parse_block(true)
|
||||
@@ -587,24 +616,24 @@ fn (mut p Parser) parse_func_decl() FuncDecl {
|
||||
|
||||
return FuncDecl {
|
||||
name: name_tok.text
|
||||
ret_type: type_tok.text
|
||||
ret_type: ret_type
|
||||
block: block
|
||||
params: params
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut p Parser) parse_struct() StructDecl {
|
||||
p.expect(.kw_struct)
|
||||
fn (mut p Parser) parse_class() ClassDecl {
|
||||
p.expect(.kw_class)
|
||||
name := p.peek().text
|
||||
p.expect(.identifier)
|
||||
p.expect(.lbracket)
|
||||
mut members := []StructMember{}
|
||||
mut members := []ClassMember{}
|
||||
for p.peek().type == .identifier {
|
||||
members << p.parse_struct_member(p.peek().text)
|
||||
members << p.parse_class_member(p.peek().text)
|
||||
}
|
||||
p.expect(.rbracket)
|
||||
p.symbols.define_struct_type(name)
|
||||
return StructDecl{name: name, members: members}
|
||||
p.symbols.define_class(name)
|
||||
return ClassDecl{name: name, members: members}
|
||||
}
|
||||
|
||||
fn (mut p Parser) parse_return_stmt() ReturnStmt {
|
||||
|
||||
Reference in New Issue
Block a user