Skip to content

Commit

Permalink
is it done already...?
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonak-Adipta-Kalita committed Apr 8, 2023
1 parent 286e953 commit b7ff95b
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 5 deletions.
44 changes: 44 additions & 0 deletions ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ast

import (
"bytes"
"strings"

"github.com/Jonak-Adipta-Kalita/JAK-Programming-Language/token"
)
Expand Down Expand Up @@ -192,3 +193,46 @@ func (ie *IfExpression) String() string {
}
return out.String()
}

type FunctionLiteral struct {
Token token.Token // The 'fn' token
Parameters []*Identifier
Body *BlockStatement
}

func (fl *FunctionLiteral) expressionNode() {}
func (fl *FunctionLiteral) TokenLiteral() string { return fl.Token.Literal }
func (fl *FunctionLiteral) String() string {
var out bytes.Buffer
params := []string{}
for _, p := range fl.Parameters {
params = append(params, p.String())
}
out.WriteString(fl.TokenLiteral())
out.WriteString("(")
out.WriteString(strings.Join(params, ", "))
out.WriteString(") ")
out.WriteString(fl.Body.String())
return out.String()
}

type CallExpression struct {
Token token.Token
Function Expression
Arguments []Expression
}

func (ce *CallExpression) expressionNode() {}
func (ce *CallExpression) TokenLiteral() string { return ce.Token.Literal }
func (ce *CallExpression) String() string {
var out bytes.Buffer
args := []string{}
for _, a := range ce.Arguments {
args = append(args, a.String())
}
out.WriteString(ce.Function.String())
out.WriteString("(")
out.WriteString(strings.Join(args, ", "))
out.WriteString(")")
return out.String()
}
9 changes: 7 additions & 2 deletions example.jonak
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ print((2 + 4 - 6 * 9) / 2);

var add = func(num1, num2) {
return num1 + num2;
};
}

var result = add(1, 2);
print(result);

if (result == 3) {
print("It works!");
} else {
print("It doesn't work!");
}
72 changes: 69 additions & 3 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ var precedences = map[token.TokenType]int{
token.MINUS: SUM,
token.SLASH: PRODUCT,
token.ASTERISK: PRODUCT,
token.LPAREN: CALL,
}

type (
Expand Down Expand Up @@ -61,6 +62,7 @@ func New(l *lexer.Lexer) *Parser {
p.registerPrefix(token.TRUE, p.parseBoolean)
p.registerPrefix(token.FALSE, p.parseBoolean)
p.registerPrefix(token.IF, p.parseIfExpression)
p.registerPrefix(token.FUNCTION, p.parseFunctionLiteral)

p.infixParseFns = make(map[token.TokenType]infixParseFn)
p.registerInfix(token.PLUS, p.parseInfixExpression)
Expand All @@ -73,6 +75,7 @@ func New(l *lexer.Lexer) *Parser {
p.registerInfix(token.GT, p.parseInfixExpression)

p.registerPrefix(token.LPAREN, p.parseGroupedExpression)
p.registerInfix(token.LPAREN, p.parseCallExpression)

p.nextToken()
p.nextToken()
Expand All @@ -96,6 +99,30 @@ func (p *Parser) curPrecedence() int {
return LOWEST
}

func (p *Parser) parseCallExpression(function ast.Expression) ast.Expression {
exp := &ast.CallExpression{Token: p.curToken, Function: function}
exp.Arguments = p.parseCallArguments()
return exp
}
func (p *Parser) parseCallArguments() []ast.Expression {
args := []ast.Expression{}
if p.peekTokenIs(token.RPAREN) {
p.nextToken()
return args
}
p.nextToken()
args = append(args, p.parseExpression(LOWEST))
for p.peekTokenIs(token.COMMA) {
p.nextToken()
p.nextToken()
args = append(args, p.parseExpression(LOWEST))
}
if !p.expectPeek(token.RPAREN) {
return nil
}
return args
}

func (p *Parser) parseBoolean() ast.Expression {
return &ast.Boolean{Token: p.curToken, Value: p.curTokenIs(token.TRUE)}
}
Expand All @@ -117,6 +144,40 @@ func (p *Parser) parseIfExpression() ast.Expression {
return expression
}

func (p *Parser) parseFunctionLiteral() ast.Expression {
lit := &ast.FunctionLiteral{Token: p.curToken}
if !p.expectPeek(token.LPAREN) {
return nil
}
lit.Parameters = p.parseFunctionParameters()
if !p.expectPeek(token.LBRACE) {
return nil
}
lit.Body = p.parseBlockStatement()
return lit
}

func (p *Parser) parseFunctionParameters() []*ast.Identifier {
identifiers := []*ast.Identifier{}
if p.peekTokenIs(token.RPAREN) {
p.nextToken()
return identifiers
}
p.nextToken()
ident := &ast.Identifier{Token: p.curToken, Value: p.curToken.Literal}
identifiers = append(identifiers, ident)
for p.peekTokenIs(token.COMMA) {
p.nextToken()
p.nextToken()
ident := &ast.Identifier{Token: p.curToken, Value: p.curToken.Literal}
identifiers = append(identifiers, ident)
}
if !p.expectPeek(token.RPAREN) {
return nil
}
return identifiers
}

func (p *Parser) parseBlockStatement() *ast.BlockStatement {
block := &ast.BlockStatement{Token: p.curToken}
block.Statements = []ast.Statement{}
Expand Down Expand Up @@ -272,12 +333,15 @@ func (p *Parser) parseVarStatement() *ast.VarStatement {
}

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

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

for !p.curTokenIs(token.SEMICOLON) {
p.nextToken()

stmt.Value = p.parseExpression(LOWEST)

if p.peekTokenIs(token.SEMICOLON) {
p.nextToken()
}

Expand All @@ -288,7 +352,9 @@ func (p *Parser) parseReturnStatement() *ast.ReturnStatement {
stmt := &ast.ReturnStatement{Token: p.curToken}
p.nextToken()

for !p.curTokenIs(token.SEMICOLON) {
stmt.ReturnValue = p.parseExpression(LOWEST)

if p.peekTokenIs(token.SEMICOLON) {
p.nextToken()
}

Expand Down

0 comments on commit b7ff95b

Please sign in to comment.