Skip to content

Commit

Permalink
feat: Integer literals parsing; and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Houcine EL ADDALI committed Dec 11, 2023
1 parent 03de669 commit 912b60f
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 4 deletions.
28 changes: 27 additions & 1 deletion AST/ast_imp.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ type ReturnStatement struct{
Token token.Token // the token is "return"
ReturnValue Expression
}

//Node interface methods
func (reStm *ReturnStatement) TokenLiteral() string{ // satisfies the node interface
return reStm.Token.Value
Expand All @@ -111,6 +112,7 @@ func (resStm *ReturnStatement) ToString() string {
bf.WriteString(";")
return bf.String()
}

// statements imp
func (reStm *ReturnStatement) statementNode() { } // satisfies the statement interface

Expand All @@ -129,6 +131,7 @@ type ExpressionStatement struct{
func (exStm *ExpressionStatement) TokenLiteral() string{
return exStm.Token.Value
}

func (exStm *ExpressionStatement) ToString() string{
var bf bytes.Buffer
if exStm.Expression !=nil {
Expand All @@ -137,4 +140,27 @@ func (exStm *ExpressionStatement) ToString() string{
return bf.String()
}

func (exStm *ExpressionStatement) statementNode(){}
func (exStm *ExpressionStatement) statementNode(){}




/*
* Integer Literals Node
* they can Occur in different type of expression's
*/
type IntegerLiteral struct {
Token token.Token
Value int // we do not specify int size to make it platform independent (32,64)
}

func (intLiteral *IntegerLiteral) TokenLiteral() string{
return intLiteral.Token.Value
}

func (intLiteral *IntegerLiteral) expressionNode() {}

func (intLiteral *IntegerLiteral) ToString() string {
return intLiteral.Token.Value
}

31 changes: 28 additions & 3 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package parser

import (
"fmt"
"strconv"

ast "github.com/houcine7/JIPL/AST"
"github.com/houcine7/JIPL/lexer"
Expand Down Expand Up @@ -45,6 +46,7 @@ func InitParser(l *lexer.Lexer) *Parser{
// init ParseFunctions maps
p.prefixParseFuncs = make(map[token.TokenType]prefixParse)
p.addPrefixFn(token.IDENTIFIER,p.parseIdentifier)
p.addPrefixFn(token.INT,p.parserInt)

return p;
}
Expand Down Expand Up @@ -79,9 +81,9 @@ func (p *Parser) Parse() *ast.Program{
for !p.currentTokenEquals(token.FILE_ENDED) {
stm := p.parseStmt()
//fmt.Println(stm.TokenLiteral())
if stm !=nil {
program.Statements =append(program.Statements, stm )
}
// if stm !=nil {
program.Statements =append(program.Statements, stm )
// }
// Advance with token
p.NextToken()
}
Expand Down Expand Up @@ -175,6 +177,29 @@ func (p *Parser) parseIdentifier() ast.Expression{
return &ast.Identifier{Token: p.currToken,Value: p.currToken.Value}
}

func (p *Parser) parserInt() ast.Expression {
exp := &ast.IntegerLiteral{Token: p.currToken}
val,err := strconv.ParseInt(p.currToken.Value,0,0)

if err !=nil {
errMsg := fmt.Sprintf("Parsing error, couldn't parse string %s to Integer value",
p.currToken.Value)
p.errors = append(p.errors, errMsg)
return nil
}

exp.Value = int(val)

return exp
}






//Helper functions

func (p *Parser) currentTokenEquals(t token.TokenType) bool{
return p.currToken.Type == t;
}
Expand Down
39 changes: 39 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,45 @@ func TestIdentifier(t *testing.T){
}
}


// Integer literals test
func TestIntegerLiteral(t *testing.T){
input :="81;"

lexer := lexer.InitLexer(input)
parser := InitParser(lexer)

pr :=parser.Parse()
checkParserErrors(parser,t)
checkIsProgramStmLengthValid(pr,t,1)

stm,ok := pr.Statements[0].(*ast.ExpressionStatement)
if !ok {
t.Fatalf("program.statement[0] is not of type expressionStatement instead got=%T",
pr.Statements[0])
}

intLiteral,ok :=stm.Expression.(*ast.IntegerLiteral)
if !ok{
t.Fatalf("stm.Expression is not of type *ast.IntegerLiteral instead got=%T",
stm.Expression)
}

if intLiteral.Value != int(81){
t.Errorf("the Integer literal value is not correct, expected=%d instead got=%d",
81,intLiteral.Value)
}

if intLiteral.TokenLiteral() !="81" {
t.Errorf("the TokenLiteral value is not correct, expected=%s instead got=%s",
"81",intLiteral.TokenLiteral())
}

}



// Tests helper functions
func checkIsProgramStmLengthValid(program *ast.Program,t *testing.T,length int){
if len(program.Statements) !=length {
t.Fatalf("the program.Statements doesn't not contain 3 statements, instead we got %d",
Expand Down

0 comments on commit 912b60f

Please sign in to comment.