class statement
This commit is contained in:
parent
c1549bbc6d
commit
0d98ae8ab1
7 changed files with 56 additions and 3 deletions
|
@ -190,3 +190,7 @@ func (as *AstStringer) visitReturnStmt(r *ReturnStmt) {
|
|||
r.value.accept(as)
|
||||
as.str.WriteString(")")
|
||||
}
|
||||
|
||||
func (as *AstStringer) visitClassStmt(c *ClassStmt) {
|
||||
fmt.Printf("(class %s)", c.name.lexeme)
|
||||
}
|
||||
|
|
9
class.go
Normal file
9
class.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
package main
|
||||
|
||||
type Class struct {
|
||||
name string
|
||||
}
|
||||
|
||||
func (c *Class) String() string {
|
||||
return c.name
|
||||
}
|
|
@ -205,6 +205,12 @@ func (i *Interpreter) visitFunStmt(f *FunStmt) {
|
|||
i.env.define(f.name.lexeme, newFunction(f.name, f.args, f.body, i.env))
|
||||
}
|
||||
|
||||
func (i *Interpreter) visitClassStmt(c *ClassStmt) {
|
||||
i.env.define(c.name.lexeme, nil)
|
||||
class := &Class{c.name.lexeme}
|
||||
i.env.assign(c.name, class)
|
||||
|
||||
}
|
||||
func (i *Interpreter) visitLambda(l *Lambda) any {
|
||||
return newFunction(l.name, l.args, l.body, i.env)
|
||||
}
|
||||
|
|
22
parser.go
22
parser.go
|
@ -48,7 +48,8 @@ func (p *Parser) parse() ([]Stmt, error) {
|
|||
return stmts, errors.Join(p.errors...)
|
||||
}
|
||||
|
||||
// declaration -> varDecl | funDecl | statement
|
||||
// declaration ->
|
||||
// varDecl | funDecl | classDecl | statement
|
||||
func (p *Parser) declaration() Stmt {
|
||||
defer p.synchronize()
|
||||
if p.match(VAR) {
|
||||
|
@ -59,6 +60,10 @@ func (p *Parser) declaration() Stmt {
|
|||
return p.function("function")
|
||||
}
|
||||
|
||||
if p.match(CLASS) {
|
||||
return p.classDecl()
|
||||
}
|
||||
|
||||
return p.statement()
|
||||
}
|
||||
|
||||
|
@ -76,10 +81,23 @@ func (p *Parser) varDecl() Stmt {
|
|||
return &VarStmt{name, initializer}
|
||||
}
|
||||
|
||||
// classDecl -> "class" IDENTIFIER "{" function* "}"
|
||||
func (p *Parser) classDecl() Stmt {
|
||||
name := p.consume(IDENTIFIER, "Expect identifier for variable")
|
||||
p.consume(LEFT_BRACE, "Expect '{' after class identifier")
|
||||
|
||||
methods := []FunStmt{}
|
||||
for !p.isAtEnd() && !p.check(RIGHT_BRACE) {
|
||||
methods = append(methods, *p.function("method"))
|
||||
}
|
||||
p.consume(RIGHT_BRACE, "Expect '}' after class definition")
|
||||
return &ClassStmt{name, methods}
|
||||
}
|
||||
|
||||
// funDecl -> "fun" function
|
||||
// function -> IDENTIFIER "(" parameters? ")" blockStmt
|
||||
// parameters -> IDENTIFIER ( "," IDENTIFIER )*
|
||||
func (p *Parser) function(kind string) Stmt {
|
||||
func (p *Parser) function(kind string) *FunStmt {
|
||||
name := p.consume(IDENTIFIER, fmt.Sprintf("Expect %s name.", kind))
|
||||
|
||||
p.consume(LEFT_PAREN, fmt.Sprintf("Expect '(' after %s name.", kind))
|
||||
|
|
|
@ -186,3 +186,8 @@ func (r *Resolver) visitUnary(u *Unary) any {
|
|||
r.resolveExprs(u.right)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Resolver) visitClassStmt(c *ClassStmt) {
|
||||
r.declare(c.name)
|
||||
r.define(c.name)
|
||||
}
|
||||
|
|
11
stmt.go
11
stmt.go
|
@ -11,6 +11,7 @@ type StmtVisitor interface {
|
|||
visitWhileStmt(w *WhileStmt)
|
||||
visitBreakStmt(b *BreakStmt)
|
||||
visitReturnStmt(r *ReturnStmt)
|
||||
visitClassStmt(c *ClassStmt)
|
||||
}
|
||||
|
||||
type Stmt interface {
|
||||
|
@ -49,6 +50,11 @@ type WhileStmt struct {
|
|||
body Stmt
|
||||
}
|
||||
|
||||
type ClassStmt struct {
|
||||
name Token
|
||||
methods []FunStmt
|
||||
}
|
||||
|
||||
type BreakStmt struct{}
|
||||
|
||||
type FunStmt struct {
|
||||
|
@ -71,6 +77,7 @@ func (b *BlockStmt) stmt() {}
|
|||
func (w *WhileStmt) stmt() {}
|
||||
func (b *BreakStmt) stmt() {}
|
||||
func (r *ReturnStmt) stmt() {}
|
||||
func (c *ClassStmt) stmt() {}
|
||||
|
||||
func (p *PrintStmt) accept(v StmtVisitor) {
|
||||
v.visitPrintStmt(p)
|
||||
|
@ -111,3 +118,7 @@ func (f *FunStmt) accept(v StmtVisitor) {
|
|||
func (r *ReturnStmt) accept(v StmtVisitor) {
|
||||
v.visitReturnStmt(r)
|
||||
}
|
||||
|
||||
func (c *ClassStmt) accept(v StmtVisitor) {
|
||||
v.visitClassStmt(c)
|
||||
}
|
||||
|
|
|
@ -68,4 +68,4 @@ fun thrice(fn) {
|
|||
|
||||
thrice(fun (a) { print a; });
|
||||
|
||||
print fun () { return "hello, "; }() + "world";
|
||||
print fun () { return "hello, "; }() + "world";
|
||||
|
|
Loading…
Reference in a new issue