Skip to content

Commit

Permalink
Merge pull request #83 from skx/null
Browse files Browse the repository at this point in the history
Null
  • Loading branch information
skx committed Jun 22, 2021
2 parents 97c31ea + e4d5eb6 commit 0152ee9
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 0 deletions.
14 changes: 14 additions & 0 deletions ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,20 @@ func (pe *PostfixExpression) String() string {
return out.String()
}

// NullLiteral represents a literal null
type NullLiteral struct {
// Token holds the actual token
Token token.Token
}

func (n *NullLiteral) expressionNode() {}

// TokenLiteral returns the literal token.
func (n *NullLiteral) TokenLiteral() string { return n.Token.Literal }

// String returns this object as a string.
func (n *NullLiteral) String() string { return n.Token.Literal }

// Boolean holds a boolean type
type Boolean struct {
// Token holds the actual token
Expand Down
2 changes: 2 additions & 0 deletions evaluator/evaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ func EvalContext(ctx context.Context, node ast.Node, env *object.Environment) ob
return &object.Float{Value: node.Value}
case *ast.Boolean:
return nativeBoolToBooleanObject(node.Value)
case *ast.NullLiteral:
return NULL
case *ast.PrefixExpression:
right := Eval(node.Right, env)
if isError(right) {
Expand Down
46 changes: 46 additions & 0 deletions lexer/lexer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,30 @@ import (
"github.com/skx/monkey/token"
)

func TestNull(t *testing.T) {
input := "a = null;"
tests := []struct {
expectedType token.Type
expectedLiteral string
}{
{token.IDENT, "a"},
{token.ASSIGN, "="},
{token.NULL, "null"},
{token.SEMICOLON, ";"},
{token.EOF, ""},
}
l := New(input)
for i, tt := range tests {
tok := l.NextToken()
if tok.Type != tt.expectedType {
t.Fatalf("tests[%d] - tokentype wrong, expected=%q, got=%q", i, tt.expectedType, tok.Type)
}
if tok.Literal != tt.expectedLiteral {
t.Fatalf("tests[%d] - Literal wrong, expected=%q, got=%q", i, tt.expectedLiteral, tok.Literal)
}
}
}

func TestNextToken1(t *testing.T) {
input := "%=+(){},;?|| &&`/bin/ls`++--***=.."

Expand Down Expand Up @@ -200,6 +224,28 @@ func TestUnicodeLexer(t *testing.T) {
}
}

func TestString(t *testing.T) {
input := `"\n\r\t\\\""`

tests := []struct {
expectedType token.Type
expectedLiteral string
}{
{token.STRING, "\n\r\t\\\""},
{token.EOF, ""},
}
l := New(input)
for i, tt := range tests {
tok := l.NextToken()
if tok.Type != tt.expectedType {
t.Fatalf("tests[%d] - tokentype wrong, expected=%q, got=%q", i, tt.expectedType, tok.Type)
}
if tok.Literal != tt.expectedLiteral {
t.Fatalf("tests[%d] - Literal wrong, expected=%q, got=%q", i, tt.expectedLiteral, tok.Literal)
}
}

}
func TestSimpleComment(t *testing.T) {
input := `=+// This is a comment
// This is still a comment
Expand Down
6 changes: 6 additions & 0 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ func New(l *lexer.Lexer) *Parser {
p.registerPrefix(token.LBRACKET, p.parseArrayLiteral)
p.registerPrefix(token.LPAREN, p.parseGroupedExpression)
p.registerPrefix(token.MINUS, p.parsePrefixExpression)
p.registerPrefix(token.NULL, p.parseNull)
p.registerPrefix(token.REGEXP, p.parseRegexpLiteral)
p.registerPrefix(token.REGEXP, p.parseRegexpLiteral)
p.registerPrefix(token.STRING, p.parseStringLiteral)
Expand Down Expand Up @@ -504,6 +505,11 @@ func (p *Parser) parseBoolean() ast.Expression {
return &ast.Boolean{Token: p.curToken, Value: p.curTokenIs(token.TRUE)}
}

// parseNull parses a null keyword
func (p *Parser) parseNull() ast.Expression {
return &ast.NullLiteral{Token: p.curToken}
}

// parsePrefixExpression parses a prefix-based expression.
func (p *Parser) parsePrefixExpression() ast.Expression {
expression := &ast.PrefixExpression{
Expand Down
2 changes: 2 additions & 0 deletions token/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const (
MOD = "%"
NOT_CONTAINS = "!~"
NOT_EQ = "!="
NULL = "null"
OR = "||"
PERIOD = "."
PLUS = "+"
Expand Down Expand Up @@ -88,6 +89,7 @@ var keywords = map[string]Type{
"if": IF,
"in": IN,
"let": LET,
"null": NULL,
"return": RETURN,
"switch": SWITCH,
"true": TRUE,
Expand Down

0 comments on commit 0152ee9

Please sign in to comment.