Skip to content
This repository has been archived by the owner on Dec 20, 2018. It is now read-only.

Commit

Permalink
Add Null-Coalescing(??) operator to the language and fix some other m…
Browse files Browse the repository at this point in the history
…inor bugs.
  • Loading branch information
haifenghuang committed Jun 5, 2018
1 parent 676c06a commit 96d537f
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/monkey/eval/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -1623,6 +1623,14 @@ func evalInfixExpression(node *ast.InfixExpression, left, right Object, scope *S
return evalInfixExpressionUDO(node, left, right, scope)
}

//Null-Coalescing Operator(??)
if node.Token.Type == token.QUESTIONMM {
if left.Type() == NIL_OBJ {
return right
}
return left
}

if isMetaOperators(node.Token.Type) {
return evalMetaOperatorInfixExpression(node, left, right, scope)
}
Expand Down
1 change: 1 addition & 0 deletions src/monkey/eval/goobject.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ func (gfn *GoFuncObject) CallMethod(line string, scope *Scope, method string, ar
outVals := reflect.ValueOf(gfn.fn).Call(inArgs)
// Convert the result back to monkey Object
for _, val := range outVals {
// Here we only retuns GoObject, See comment of 'RegisterVars'.
results = append(results, NewGoObject(val.Interface()))
// switch val.Kind() {
// case reflect.Bool:
Expand Down
7 changes: 7 additions & 0 deletions src/monkey/lexer/lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,13 @@ func (l *Lexer) NextToken() token.Token {
} else {
tok = newToken(token.BITXOR, l.ch)
}
case token.QUESTIONM:
if l.peek() == '?' {
tok = token.Token{Type: token.QUESTIONMM, Literal: string(l.ch) + string(l.peek())}
l.readNext()
} else {
tok = newToken(token.QUESTIONM, l.ch)
}
default:
tok = newToken(t, l.ch)
}
Expand Down
8 changes: 8 additions & 0 deletions src/monkey/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const (
FATARROW
CONDOR
CONDAND
NULLCOALESCING //??
EQUALS
LESSGREATER
BITOR
Expand Down Expand Up @@ -76,6 +77,7 @@ var precedences = map[token.TokenType]int{
token.SHIFT_R: SHIFTS,
token.COLON: SLICE,
token.QUESTIONM: TERNARY,
token.QUESTIONMM: NULLCOALESCING,
token.DOTDOT: DOTDOT,
token.PLUS: SUM,
token.MINUS: SUM,
Expand Down Expand Up @@ -255,6 +257,7 @@ func (p *Parser) registerAction() {
p.registerInfix(token.BITOR, p.parseInfixExpression)
p.registerInfix(token.BITXOR, p.parseInfixExpression)
p.registerInfix(token.UDO, p.parseInfixExpression)
p.registerInfix(token.QUESTIONMM, p.parseInfixExpression)

p.registerInfix(token.ASSIGN, p.parseAssignExpression)
p.registerInfix(token.PLUS_A, p.parseAssignExpression)
Expand Down Expand Up @@ -762,6 +765,11 @@ func (p *Parser) parseLetStatement() *ast.LetStatement {
if p.curTokenIs(token.ASSIGN) || p.curTokenIs(token.SEMICOLON) {
break
}
if !p.curTokenIs(token.COMMA) {
msg := fmt.Sprintf("Syntax Error:%v- expected token to be comma, got %s instead.", p.curToken.Pos, p.curToken.Type)
p.errors = append(p.errors, msg)
return stmt
}
}

if p.curTokenIs(token.SEMICOLON) { //let x;
Expand Down
4 changes: 4 additions & 0 deletions src/monkey/token/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ const (
TILDECARET // ~^

USING
QUESTIONMM // ?? (Null Coalescing Operator)

)

var keywords = map[string]TokenType{
Expand Down Expand Up @@ -369,6 +371,8 @@ func (tt TokenType) String() string {
return "THROW"
case QUESTIONM:
return "?"
case QUESTIONMM:
return "??"
case DEFER:
return "DEFER"
case NIL:
Expand Down

0 comments on commit 96d537f

Please sign in to comment.