Function arguments

This commit is contained in:
uan
2026-02-04 22:21:18 +01:00
parent ab5559d206
commit 6c9679ff57
2 changed files with 84 additions and 29 deletions

View File

@@ -147,11 +147,12 @@ struct PrintExpr {
struct FnCall {
name string
args []Expr
}
// ------------------------------------------- Statements
type Stmt = VarDecl | ExprStmt | ReturnStmt | Block | FuncDecl
type Stmt = VarDecl | ExprStmt | ReturnStmt | Block | FuncDecl | Param
struct VarDecl {
name string
@@ -162,6 +163,7 @@ struct VarDecl {
struct FuncDecl {
name string
params []Param
ret_type string
block Block
}
@@ -178,6 +180,11 @@ struct Block {
stmts []Stmt
}
struct Param {
name string
type string
}
// ------------------------------------------- Parser
struct Parser {
@@ -185,6 +192,7 @@ struct Parser {
mut:
symbols SymbolTable
pos int
line int
statements []Stmt
}
@@ -223,7 +231,7 @@ fn (mut p Parser) dump_stmt() {
@[noreturn]
fn parse_error(str string) {
eprintln(term.red("Parse Error: " + str))
eprintln(term.red("Parse Error: ${str}"))
panic("")
}
@@ -259,16 +267,29 @@ fn (mut p Parser) parse_expr(prec Precedence) Expr {
}
fn (mut p Parser) parse_ident(ident string) Expr {
expr := match p.peek().type {
.increment, .decrement {Expr(UnaryExpr {ident: ident, op: p.next().text})}
.lparen {
p.expect(.lparen)
p.expect(.rparen)
FnCall{name: ident}
}
return match p.peek().type {
.increment, .decrement {UnaryExpr {ident: ident, op: p.next().text}}
.lparen {p.parse_call(ident)}
else {Variable{ident, p.symbols.variable_scopes.len}}
}
return expr
}
fn (mut p Parser) parse_call(name string) FnCall {
p.expect(.lparen)
mut args := []Expr{}
if p.peek().type != .rparen {
for {
args << p.parse_expr(.lowest)
if p.peek().type == .comma {
p.next()
} else {
break
}
}
}
p.expect(.rparen)
return FnCall{name: name, args: args}
}
fn (mut p Parser) parse_print() PrintExpr {
@@ -317,7 +338,7 @@ fn (mut p Parser) check_binary_expr_types(expr BinaryExpr) {
left_t := p.get_expr_type(expr.left)
right_t := p.get_expr_type(expr.right)
if left_t != right_t {
parse_error ('Type mismatch in expression: ${left_t} and ${right_t}')
parse_error('Type mismatch in expression: ${left_t} and ${right_t}')
}
}
@@ -439,6 +460,28 @@ fn (mut p Parser) parse_func_decl() FuncDecl {
}
p.expect(.lparen)
mut params := []Param{}
p.symbols.variable_scopes << map[string]VarSymbolInfo{}
if p.peek().type != .rparen {
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
params << Param{p_name, p_type}
p.symbols.define_var(p_name, p_type)
if p.peek().type == .comma {
p.next()
} else {
break
}
}
}
p.expect(.rparen)
p.dump_token()
@@ -448,7 +491,6 @@ fn (mut p Parser) parse_func_decl() FuncDecl {
parse_error("Expected function return type after name when declaring ${name_tok.text}")
}
p.symbols.variable_scopes << map[string]VarSymbolInfo{}
block := p.parse_block(true)
return_stmts := p.get_return_stmts_recursive(block)
@@ -468,26 +510,17 @@ fn (mut p Parser) parse_func_decl() FuncDecl {
name: name_tok.text
ret_type: type_tok.text
block: block
params: params
}
}
fn (mut p Parser) parse_return_stmt() ReturnStmt {
p.expect(.kw_return)
token := p.peek()
mut expr := Expr{}
expr = match token.type {
.integer {IntegerLiteral{token.text.int()}}
.real {RealLiteral{token.text.f32()}}
.boolean {BoolLiteral{token.text == 'true'}}
.identifier {Variable{token.text, p.symbols.variable_scopes.len}}
.semicolon {VoidExpr{}}
else {parse_error("Unexpected Token")}
}
expr := p.parse_expr(.lowest)
p.next()
if !(expr is VoidExpr) {
p.expect(.semicolon)
}
return ReturnStmt {
expr: expr
}