Skip to content

Commit

Permalink
add module operator
Browse files Browse the repository at this point in the history
  • Loading branch information
gravataLonga committed Jul 3, 2022
1 parent 64ae552 commit e3862c4
Show file tree
Hide file tree
Showing 17 changed files with 102 additions and 29 deletions.
61 changes: 58 additions & 3 deletions evaluator/digit_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package evaluator

import (
"fmt"
"testing"
)

Expand Down Expand Up @@ -36,11 +37,65 @@ func TestEvalDigitExpression(t *testing.T) {
{
`[1, 3.0][1] + 1.2`,
4.2,
}, {
`1 - 1`,
0,
},
{
`1.0 - 1.0`,
0.0,
},
{
`1 - 1.0`,
0.0,
},
{
`1.0 - 1`,
0.0,
},
{
`1.0 - 1`,
0.0,
},
{
`[1.0, 3.0][1] - 1`,
2.0,
},
{
`[1, 3.0][1] - 1.2`,
1.8,
},
{
`2 * 2`,
4,
},
{
`4 / 2`,
2,
},
{
`4 % 2`,
0,
},
{
`4.0 % 2.0`,
0.0,
},
{
`4 % 2.0`,
0.0,
},
{
`4.0 % 2`,
0.0,
},
}

for _, tt := range tests {
evaluated := testEval(tt.input, t)
testObjectLiteral(t, evaluated, tt.expected)
for i, tt := range tests {
t.Run(fmt.Sprintf("TestEvalDigitExpression[%d]", i), func(t *testing.T) {
evaluated := testEval(tt.input, t)
testObjectLiteral(t, evaluated, tt.expected)
})

}
}
3 changes: 3 additions & 0 deletions evaluator/float.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package evaluator

import (
"math"
"ninja/object"
)

Expand All @@ -18,6 +19,8 @@ func evalFloatInfixExpression(
return &object.Float{Value: leftVal - rightVal}
case "*":
return &object.Float{Value: leftVal * rightVal}
case "%":
return &object.Float{Value: math.Mod(leftVal, rightVal)}
case "/":
return &object.Float{Value: leftVal / rightVal}
case "<":
Expand Down
2 changes: 2 additions & 0 deletions evaluator/integer.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ func evalIntegerInfixExpression(
return &object.Integer{Value: leftVal - rightVal}
case "*":
return &object.Integer{Value: leftVal * rightVal}
case "%":
return &object.Integer{Value: leftVal % rightVal}
case "/":
return &object.Integer{Value: leftVal / rightVal}
case "<":
Expand Down
17 changes: 4 additions & 13 deletions lexer/lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,9 @@ func (l *Lexer) NextToken() token.Token {
l.skipWhitespace()
switch l.ch {
case '=':

tok = l.newTokenPeekOrDefault(token.ASSIGN, map[byte]token.TokenType{
'=': token.EQ,
})

case ';':
tok = l.newToken(token.SEMICOLON, []byte{l.ch})
case '"':
Expand Down Expand Up @@ -71,7 +69,6 @@ func (l *Lexer) NextToken() token.Token {
l.readChar()
tok = l.newToken(token.AND, []byte{ch, l.ch})
}

case '|':
if l.peekChar() != '|' {
ch := l.ch
Expand All @@ -82,36 +79,30 @@ func (l *Lexer) NextToken() token.Token {
l.readChar()
tok = l.newToken(token.OR, []byte{ch, l.ch})
}

case '-':

tok = l.newTokenPeekOrDefault(token.MINUS, map[byte]token.TokenType{
'-': token.DECRE,
})

case '+':

tok = l.newTokenPeekOrDefault(token.PLUS, map[byte]token.TokenType{
'+': token.INCRE,
})
case '%':
tok = l.newTokenPeekOrDefault(token.MOD, map[byte]token.TokenType{
'%': token.MOD,
})
case '>':

tok = l.newTokenPeekOrDefault(token.GT, map[byte]token.TokenType{
'=': token.GTE,
})

case '<':

tok = l.newTokenPeekOrDefault(token.LT, map[byte]token.TokenType{
'=': token.LTE,
})

case '!':

tok = l.newTokenPeekOrDefault(token.BANG, map[byte]token.TokenType{
'=': token.NEQ,
})

case ':':
tok = l.newToken(token.COLON, []byte{l.ch})
case '(':
Expand Down
10 changes: 6 additions & 4 deletions lexer/lexer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func TestNextToken(t *testing.T) {
var true false if else
break for () [] {} . ; :
!= == <= >= < > && || =
+ - * /
+ - * / %
// comment
! 100 100.5 "hello"
++5 --5 5++ 5-- count
Expand Down Expand Up @@ -55,6 +55,8 @@ function delete @
{token.MINUS, "-"},
{token.ASTERISK, "*"},
{token.SLASH, "/"},

{token.MOD, "%"},
{token.BANG, "!"},

{token.INT, "100"},
Expand All @@ -79,13 +81,13 @@ function delete @
l := New(strings.NewReader(input))

for i, tt := range tests {
t.Run(fmt.Sprintf("Test_%s", tt.expectedType.String()), func(t *testing.T) {
t.Run(fmt.Sprintf("Test[%d]", i), func(t *testing.T) {
tok := l.NextToken()
if tok.Type != tt.expectedType {
t.Fatalf("tests[%d] - tokentype wrong. expected=%q, got=%q", i, tt.expectedType, tok.Type)
t.Fatalf("testdata[%d] - tokentype wrong. expected=%q, got=%q", i, tt.expectedType, tok.Type)
}
if string(tok.Literal) != tt.expectedLiteral {
t.Fatalf("tests[%d] - literal wrong. expected=%q, got=%q", i, tt.expectedLiteral, tok.Literal)
t.Fatalf("testdata[%d] - literal wrong. expected=%q, got=%q", i, tt.expectedLiteral, tok.Literal)
}
})

Expand Down
6 changes: 3 additions & 3 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func TestMain_execCodeSpecialCharacter(t *testing.T) {
defer os.Remove(temporaryStdOut.Name())
os.Stdout = temporaryStdOut

execCode("import \"./tests/multiple_lines.nj\"; input.split(\"\n\")", temporaryStdOut)
execCode("import \"./testdata/multiple_lines.nj\"; input.split(\"\n\")", temporaryStdOut)

resultOut, err := os.ReadFile(temporaryStdOut.Name())
if err != nil {
Expand All @@ -118,8 +118,8 @@ func TestMain_execCodeAssertions(t *testing.T) {
defer os.Remove(temporaryStdOut.Name())
os.Stdout = temporaryStdOut

code := readFile(t, "./tests/assertions.nj")
expected := readFile(t, "./tests/expected.txt")
code := readFile(t, "./testdata/assertions.nj")
expected := readFile(t, "./testdata/expected.txt")
execCode(code, temporaryStdOut)

resultOut, err := os.ReadFile(temporaryStdOut.Name())
Expand Down
13 changes: 10 additions & 3 deletions object/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@ package object
import "io"

var (
Arguments []string
StandardInput io.Reader
// Arguments is argument that is passed from CLI arguments
Arguments []string

// StandardInput where is standard input
StandardInput io.Reader

// StandardOutput where is standard output
StandardOutput io.Writer
ExitFunction func(int)

// ExitFunction where function responsible for exit
ExitFunction func(int)
)
1 change: 1 addition & 0 deletions parser/float_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func TestFloatLiteralExpression(t *testing.T) {
}

for i, tt := range tests {

stmt, ok := program.Statements[i].(*ast.ExpressionStatement)
if !ok {
t.Fatalf("program.Statements[%d] is not ast.ExpressionStatement. got=%T", i, program.Statements[i])
Expand Down
2 changes: 2 additions & 0 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ var precedences = map[token.TokenType]int{
token.INCRE: SUM,
token.SLASH: PRODUCT,
token.ASTERISK: PRODUCT,
token.MOD: PRODUCT,
token.LPAREN: CALL,
token.LBRACKET: INDEX,
token.DOT: CALL,
Expand Down Expand Up @@ -92,6 +93,7 @@ func New(l *lexer.Lexer) *Parser {
p.registerInfix(token.MINUS, p.parseInfixExpression)
p.registerInfix(token.SLASH, p.parseInfixExpression)
p.registerInfix(token.ASTERISK, p.parseInfixExpression)
p.registerInfix(token.MOD, p.parseInfixExpression)
p.registerInfix(token.EQ, p.parseInfixExpression)
p.registerInfix(token.NEQ, p.parseInfixExpression)
p.registerInfix(token.LT, p.parseInfixExpression)
Expand Down
8 changes: 8 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ func TestOperatorPrecedenceParsing(t *testing.T) {
"a + b * c + d / e - f",
"(((a + (b * c)) + (d / e)) - f)",
},
{
"a + b % c",
"(a + (b % c))",
},
{
"a * b % c",
"((a * b) % c)",
},
{
"3 + 4; -5 * 5",
"(3 + 4)((-5) * 5)",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions tests/assertions.nj → testdata/assertions.nj
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ function assertTrue() {
Assertion basic variables
*/

import "./tests/assert_variable.nj";
import "./testdata/assert_variable.nj";

/*
Assertion Index
*/

import "./tests/assert_index.nj";
import "./testdata/assert_index.nj";


/*
Assertion advance stuff
*/

import "./tests/assert_advance.nj";
import "./testdata/assert_advance.nj";
File renamed without changes.
File renamed without changes.
2 changes: 2 additions & 0 deletions token/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func (t TokenType) String() string {
"-",
"!",
"*",
"%",
"/",
"++",
"--",
Expand Down Expand Up @@ -90,6 +91,7 @@ const (
MINUS // "-"
BANG // "!"
ASTERISK // "*"
MOD // "%"
SLASH // "/"
INCRE // "++"
DECRE // "--"
Expand Down

0 comments on commit e3862c4

Please sign in to comment.