Skip to content

Commit

Permalink
can parse classes
Browse files Browse the repository at this point in the history
  • Loading branch information
sevenreup committed Aug 15, 2024
1 parent ab6aa6f commit ad820ab
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 8 deletions.
31 changes: 31 additions & 0 deletions src/ast/class.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package ast

import (
"bytes"

"github.com/sevenreup/chewa/src/token"
)

type ClassStatement struct {
Expression
Token token.Token
Name *Identifier
Super *Identifier
Body *BlockStatement
}

func (class *ClassStatement) expressionNode() {}
func (class *ClassStatement) TokenLiteral() string { return class.Token.Literal }
func (class *ClassStatement) String() string {
var out bytes.Buffer
out.WriteString("ndondomeko ")
out.WriteString(class.Name.String())
if class.Super != nil {
out.WriteString(" ndi ")
out.WriteString(class.Super.String())
}
out.WriteString(" {\n")
out.WriteString(class.Body.String())
out.WriteString("\n}")
return out.String()
}
24 changes: 24 additions & 0 deletions src/parser/class.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package parser

import (
"github.com/sevenreup/chewa/src/ast"
"github.com/sevenreup/chewa/src/token"
)

func (p *Parser) classStatement() ast.Expression {
class := &ast.ClassStatement{Token: p.curToken}

p.nextToken()

class.Name = &ast.Identifier{Token: p.curToken, Value: p.curToken.Literal}

// TODO: Implement inheritance

if !p.expectPeek(token.OPENING_BRACE) {
return nil
}

class.Body = p.parseBlockStatement()

return class
}
1 change: 1 addition & 0 deletions src/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func New(l *lexer.Lexer) *Parser {
p.registerPrefix(token.FOR, p.parseForExpression)
p.registerPrefix(token.WHILE, p.parseWhileExpression)
p.registerPrefix(token.FUNCTION, p.parseFunctionLiteral)
p.registerPrefix(token.CLASS, p.classStatement)

p.registerPrefix(token.OPENING_BRACE, p.mapLiteral)
p.registerPrefix(token.OPENING_PAREN, p.parseGroupedExpression)
Expand Down
18 changes: 10 additions & 8 deletions src/parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1346,24 +1346,26 @@ func TestParsingHashLiteralsWithExpressions(t *testing.T) {

func TestParsingClassExpressions(t *testing.T) {
input := `
kalasi Person {
kalasi Person {
nambala age = 5;
}`
l := lexer.New([]byte(input))
p := New(l)
program := p.ParseProgram()
checkParserErrors(t, p)
stmt := program.Statements[0].(*ast.ClassStatement)
if stmt.Name.Value != "Person" {
t.Fatalf("stmt.Name.Value not 'Person'. got=%q", stmt.Name.Value)
stmt := program.Statements[0].(*ast.ExpressionStatement)
classStatement := stmt.Expression.(*ast.ClassStatement)
if classStatement.Name.Value != "Person" {
t.Fatalf("stmt.Name.Value not 'Person'. got=%q", classStatement.Name.Value)
}
if len(stmt.Body.Statements) != 1 {
if len(classStatement.Body.Statements) != 1 {
t.Fatalf("stmt.Body.Statements does not contain 1 statements. got=%d\n",
len(stmt.Body.Statements))
len(classStatement.Body.Statements))
}
bodyStmt, ok := stmt.Body.Statements[0].(*ast.VariableDeclarationStatement)
bodyStmt, ok := classStatement.Body.Statements[0].(*ast.VariableDeclarationStatement)
if !ok {
t.Fatalf("stmt.Body.Statements[0] is not ast.VariableDeclarationStatement. got=%T",
stmt.Body.Statements[0])
classStatement.Body.Statements[0])
}
if bodyStmt.Identifier.Value != "age" {
t.Fatalf("bodyStmt.Identifier.Value not 'age'. got=%s", bodyStmt.Identifier.Value)
Expand Down
2 changes: 2 additions & 0 deletions src/token/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const (
FOR = "FOR"
WHILE = "WHILE"
MAP = "MAP"
CLASS = "CLASS"
)

type Position struct {
Expand All @@ -89,6 +90,7 @@ var keywords = map[string]TokenType{
"za": FOR,
"pamene": WHILE,
"mgwirizano": MAP,
"kalasi": CLASS,
}

var variableTypes = map[TokenType]TokenType{
Expand Down

0 comments on commit ad820ab

Please sign in to comment.