diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index c78830b..f02ede8 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,13 +4,11 @@
-
+
-
-
-
+
@@ -60,6 +58,14 @@
+
+
+
+
+
+
+
+
@@ -80,6 +86,15 @@
+
+
+
+
+
+
+
+
+
@@ -98,7 +113,8 @@
-
+
+
true
diff --git a/lexer/lexer.go b/lexer/lexer.go
index 520ec29..5509c82 100644
--- a/lexer/lexer.go
+++ b/lexer/lexer.go
@@ -1,6 +1,7 @@
package lexer
import (
+ "regexp"
"strings"
"text/scanner"
)
@@ -8,47 +9,48 @@ import (
type TokenType int
const (
- EOF TokenType = iota
- LPAREN
- RPAREN
- COMMA
- IDENTIFIER
- NUMBER
- STRING
- EQUAL
- ASSIGN
- VAR
- BOOL
- MODULO
- DIVIDE
- PLUS
- MULTIPLY
- SUBTRACT
- PLUS_ASSIGN
- SUBTRACT_ASSIGN
- MULTIPLY_ASSIGN
- DIVIDE_ASSIGN
- MODULO_ASSIGN
- LEFT_SHIFT_ASSIGN
- RIGHT_SHIFT_ASSIGN
- BITWISE_AND_ASSIGN
- BITWISE_XOR_ASSIGN
- PLUS_PLUS
- SUBTRACT_SUBTRACT
- BITWISE_XOR
- LEFT_SHIFT
- RIGHT_SHIFT
- BITWISE_AND
- EQUAL_TO
- NOT_EQUAL_TO
- LESS_THAN
- LESS_THAN_OR_EQUAL
- GREATER_THAN
- GREATER_THAN_TO_EQUAL
- AND
- L
+ EOF TokenType = iota // end of file
+ LPAREN // (
+ RPAREN // )
+ COMMA // ,
+ IDENTIFIER // variable identifier
+ NUMBER // numeric literal
+ STRING // string literal
+ EQUAL // ==
+ ASSIGN // =
+ VAR // var keyword
+ BOOL // boolean literal
+ MODULO // %
+ DIVIDE // /
+ PLUS // +
+ MULTIPLY // *
+ SUBTRACT // -
+ PLUS_ASSIGN // +=
+ SUBTRACT_ASSIGN // -=
+ MULTIPLY_ASSIGN // *=
+ DIVIDE_ASSIGN // /=
+ MODULO_ASSIGN // %=
+ LEFT_SHIFT_ASSIGN // <<=
+ RIGHT_SHIFT_ASSIGN // >>=
+ BITWISE_AND_ASSIGN // &=
+ BITWISE_XOR_ASSIGN // ^=
+ PLUS_PLUS // ++
+ SUBTRACT_SUBTRACT // --
+ BITWISE_XOR // ^
+ LEFT_SHIFT // <<
+ RIGHT_SHIFT // >>
+ BITWISE_AND // &
+ EQUAL_TO // ==
+ NOT_EQUAL_TO // !=
+ LESS_THAN // <
+ LESS_THAN_OR_EQUAL // <=
+ GREATER_THAN // >
+ GREATER_THAN_TO_EQUAL // >=
+ AND // &&
)
+var numReg = regexp.MustCompile(`\d`)
+
type Token struct {
Type TokenType
Value string
@@ -102,7 +104,10 @@ func (l *Lexer) NextToken() Token {
if l.Scanner.Peek() == '=' {
l.NextToken()
return Token{Type: SUBTRACT_ASSIGN, Value: "-="}
+ } else if numReg.MatchString(string(l.Scanner.Peek())) {
+ return Token{Type: NUMBER, Value: "-" + l.NextToken().Value}
}
+
return Token{Type: SUBTRACT, Value: val}
case '*':
if l.Scanner.Peek() == '=' {
diff --git a/lexer/lexerArithmeticOperations.go b/lexer/lexerArithmeticOperations.go
index 272643d..cc24501 100644
--- a/lexer/lexerArithmeticOperations.go
+++ b/lexer/lexerArithmeticOperations.go
@@ -46,23 +46,35 @@ func IsMathExpression(curT Token, secondT Token, lexer *Lexer) bool { //10 +
return false
}
-//func ReplaceAllIdentsWithValue(c Token, s Token, l *Lexer) (interface{}, error) {
-// switch c.Type {
-// case IDENTIFIER:
-// if s.Type == RPAREN {
-// funName, args, err := ParseFunctionCall(c, s, l)
-// if err != nil {
-// return nil, err
-// }
-//
-// }
-// va, ok := std.Variables[c.Value]
-// if !ok {
-// return nil, fmt.Errorf("'%s' is not defined", c.Value)
-// }
-// return va, nil
-//
-// default:
-// return nil, nil
-// }
-//}
+func ReplaceAllIdentsWithValue(c Token, s Token, l *Lexer) (interface{}, error) {
+ return nil, nil
+}
+func MathExpressionTokensToEnd(c Token, s Token, l *Lexer) ([]Token, error) {
+ var tokenArr []Token
+ RPcount, LPcount := 0, 0
+
+ if s.Type == RPAREN {
+ tokenArr = append(tokenArr, s)
+ RPcount++
+ }
+ switch c.Type {
+ case IDENTIFIER:
+ if s.Type == LPAREN {
+ //function
+ }
+
+ //variable
+ case BOOL, NUMBER:
+ tokenArr = append(tokenArr, c)
+ case LPAREN:
+ tokenArr = append(tokenArr, c)
+ LPcount++
+
+ case RPAREN:
+ return nil, fmt.Errorf("first token to a math expression can't be a ')'")
+ }
+ if LPcount != RPcount {
+ return nil, fmt.Errorf("invalid left/right parentheses count")
+ }
+ return tokenArr, nil
+}
diff --git a/lexer/lexerVariableOperator.go b/lexer/lexerVariableOperator.go
index 5c5c2e4..268d425 100644
--- a/lexer/lexerVariableOperator.go
+++ b/lexer/lexerVariableOperator.go
@@ -33,17 +33,28 @@ it detects its a expression, then u can to lexer.NextToken()
func IsVariableExpression(curT Token, exp Token, lexer *Lexer) bool {
//pk := lexer.Scanner.Peek()
- return curT.Type == IDENTIFIER && (exp.Type == PLUS_ASSIGN || exp.Type == SUBTRACT_ASSIGN || exp.Type == MULTIPLY_ASSIGN || exp.Type == DIVIDE_ASSIGN || exp.Type == MODULO_ASSIGN) //pk != '(' //(pk == '+' || pk == '-' || pk == '*' || pk == '/' || pk == '%' || pk == '=')
+ return curT.Type == IDENTIFIER && (exp.Type == ASSIGN || exp.Type == PLUS_ASSIGN || exp.Type == SUBTRACT_ASSIGN || exp.Type == MULTIPLY_ASSIGN || exp.Type == DIVIDE_ASSIGN || exp.Type == MODULO_ASSIGN) //pk != '(' //(pk == '+' || pk == '-' || pk == '*' || pk == '/' || pk == '%' || pk == '=')
}
func ParseVariableAssigningExpression(key Token, expression Token, value Token, lexer *Lexer) (output int, err error) {
exp := expression
- if value.Type != NUMBER && value.Type != IDENTIFIER {
- return 0, fmt.Errorf("expected an integer, but got '%s'", value.Value)
+ if value.Type != NUMBER && value.Type != IDENTIFIER && value.Type != BOOL {
+ if exp.Type != ASSIGN {
+ return 0, fmt.Errorf("expected an integer, but got '%s'", value.Value)
+ }
+
+ }
+ if exp.Type != ASSIGN && value.Type == BOOL {
+ return 0, fmt.Errorf("booleans only support '=' operator for assigning")
}
if key.Type != IDENTIFIER {
return 0, fmt.Errorf("expected an identifier, but got '%s'", key.Value)
}
+
k, ok := std.Variables[key.Value]
+ if value.Type == BOOL && expression.Type == ASSIGN {
+ std.Variables[key.Value] = value.Value == "true"
+ return 0, err
+ }
if !ok {
return 0, fmt.Errorf("'%s' is not defined", key.Value)
}
@@ -51,11 +62,16 @@ func ParseVariableAssigningExpression(key Token, expression Token, value Token,
return 0, fmt.Errorf("can not do math operations on a non integer '%s'", key.Value)
}
vals, err := ParseExpression(value, lexer)
- valI := vals.(int)
+
+ valI, ok := vals.(int)
+
if err != nil {
return 0, err
}
+ if !ok {
+ return 0, nil
+ }
switch exp.Type {
case PLUS_ASSIGN:
std.Variables[key.Value] = k.(int) + valI