diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index c8920f4..c78830b 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,12 +4,13 @@
-
+
-
+
+
@@ -59,14 +60,6 @@
-
-
-
-
-
-
-
-
@@ -87,15 +80,6 @@
-
-
-
-
-
-
-
-
-
@@ -113,7 +97,8 @@
-
+
+
true
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..bb59ab5
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,2 @@
+github.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg=
+github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
diff --git a/interpreter/interpret.go b/interpreter/interpret.go
index e8f3b5b..d35f079 100644
--- a/interpreter/interpret.go
+++ b/interpreter/interpret.go
@@ -16,6 +16,7 @@ func Interpret(input string) {
if curT.Type == lx.EOF {
break
}
+
if lx.IsVariableExpression(curT, secondT, lexer) { // key +
key := curT
exp := secondT
diff --git a/lexer/lexer.go b/lexer/lexer.go
index d00a824..520ec29 100644
--- a/lexer/lexer.go
+++ b/lexer/lexer.go
@@ -29,6 +29,24 @@ const (
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
)
type Token struct {
diff --git a/lexer/lexerArithmeticOperations.go b/lexer/lexerArithmeticOperations.go
index 572bf01..272643d 100644
--- a/lexer/lexerArithmeticOperations.go
+++ b/lexer/lexerArithmeticOperations.go
@@ -6,7 +6,7 @@ import (
"github.com/Knetic/govaluate"
)
-func ParseArithmeticExpressions(expression string) (int, error) {
+func ParseArithmeticExpressions(expression string) (any, error) {
// Create new expression with default token factory
expr, err := govaluate.NewEvaluableExpression(expression)
if err != nil {
@@ -20,8 +20,49 @@ func ParseArithmeticExpressions(expression string) (int, error) {
}
// Convert result to int and return
+ if result == "true" || result == "false" {
+ return result == "true", nil
+ }
if val, ok := result.(float64); ok {
return int(val), nil
}
return 0, fmt.Errorf("Error converting result to int")
}
+func IsMathExpression(curT Token, secondT Token, lexer *Lexer) bool { //10 +
+
+ switch curT.Type {
+ case LPAREN:
+ switch secondT.Type {
+ case IDENTIFIER, NUMBER, BOOL:
+ return true
+ default:
+ return false
+ }
+ case NUMBER:
+ switch secondT.Type {
+ //case :
+ }
+ }
+ 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
+// }
+//}
diff --git a/lexer/lexerFunction.go b/lexer/lexerFunction.go
index e1c3566..aab2b1f 100644
--- a/lexer/lexerFunction.go
+++ b/lexer/lexerFunction.go
@@ -58,7 +58,7 @@ func ParseExpression(tok Token, lexer *Lexer) (interface{}, error) {
return tok.Value[1 : len(tok.Value)-1], nil
case IDENTIFIER:
if p := lexer.Scanner.Peek(); p != '(' {
- if val, ok := Variables[tok.Value]; ok {
+ if val, ok := std.Variables[tok.Value]; ok {
return val, nil
}
return nil, errors.New(fmt.Sprintf("'%s' is not defined", tok.Value))
diff --git a/lexer/lexerVariable.go b/lexer/lexerVariable.go
index ae5c3aa..ae02bce 100644
--- a/lexer/lexerVariable.go
+++ b/lexer/lexerVariable.go
@@ -1,15 +1,12 @@
package lexer
import (
+ "RedoLanguage/std"
"errors"
"fmt"
"strconv"
)
-var Variables = map[string]any{
- "hello": 10,
-}
-
func RuneToStr(ch rune) string {
return fmt.Sprintf(`%q`, string(ch))
}
@@ -39,12 +36,12 @@ func ParseVariable(curToken Token, sec Token, lexer *Lexer) (key string, value i
if VariableExists(keyT.Value) {
return "", nil, errors.New(fmt.Sprintf("'%s' is already declared", keyT.Value))
}
- Variables[keyT.Value] = parsedVal
+ std.Variables[keyT.Value] = parsedVal
return keyT.Value, parsedVal, nil
}
func VariableExists(name string) bool {
- return Variables[name] != nil
+ return std.Variables[name] != nil
}
func parseVariableValue(token Token) (interface{}, error) {
switch token.Type {
@@ -80,7 +77,7 @@ func parseVariableValue(token Token) (interface{}, error) {
}
func parseIdentifier(token Token) (interface{}, error) {
- if val, ok := Variables[token.Value]; ok {
+ if val, ok := std.Variables[token.Value]; ok {
return val, nil
}
return nil, fmt.Errorf("undefined identifier: %s", token.Value)
diff --git a/lexer/lexerVariableOperator.go b/lexer/lexerVariableOperator.go
index ed4c27a..5c5c2e4 100644
--- a/lexer/lexerVariableOperator.go
+++ b/lexer/lexerVariableOperator.go
@@ -1,6 +1,7 @@
package lexer
import (
+ "RedoLanguage/std"
"fmt"
"reflect"
)
@@ -42,7 +43,7 @@ func ParseVariableAssigningExpression(key Token, expression Token, value Token,
if key.Type != IDENTIFIER {
return 0, fmt.Errorf("expected an identifier, but got '%s'", key.Value)
}
- k, ok := Variables[key.Value]
+ k, ok := std.Variables[key.Value]
if !ok {
return 0, fmt.Errorf("'%s' is not defined", key.Value)
}
@@ -57,23 +58,23 @@ func ParseVariableAssigningExpression(key Token, expression Token, value Token,
}
switch exp.Type {
case PLUS_ASSIGN:
- Variables[key.Value] = k.(int) + valI
+ std.Variables[key.Value] = k.(int) + valI
return k.(int) + valI, nil
case SUBTRACT_ASSIGN:
- Variables[key.Value] = k.(int) - valI
+ std.Variables[key.Value] = k.(int) - valI
return k.(int) - valI, nil
case MULTIPLY_ASSIGN:
- Variables[key.Value] = k.(int) * valI
+ std.Variables[key.Value] = k.(int) * valI
return k.(int) * valI, nil
case DIVIDE_ASSIGN:
- Variables[key.Value] = k.(int) / valI
+ std.Variables[key.Value] = k.(int) / valI
return k.(int) / valI, nil
case MODULO_ASSIGN:
//fmt.Println(k.(int) % valI)
- Variables[key.Value] = k.(int) % valI
+ std.Variables[key.Value] = k.(int) % valI
return k.(int) % valI, nil
case ASSIGN:
- Variables[key.Value] = valI
+ std.Variables[key.Value] = valI
return valI, nil
}
return 0, nil
diff --git a/main.go b/main.go
index 551ffce..e0ae780 100644
--- a/main.go
+++ b/main.go
@@ -11,6 +11,10 @@ import (
func main() {
//
//n := lx.NewLexer(`(10+10)*10`)
+ //l := lx.NewLexer("10 + 10 * 10")
+ //
+ //fmt.Println(lx.IsMathExpression(l.NextToken(), l.NextToken(), l))
+ //os.Exit(1)
//fmt.Print(lx.ParseArithmeticExpressions(n.NextToken(), n.NextToken(), n))
for {
reader := bufio.NewReader(os.Stdin)
diff --git a/std/Variables.go b/std/Variables.go
new file mode 100644
index 0000000..bb84304
--- /dev/null
+++ b/std/Variables.go
@@ -0,0 +1,3 @@
+package std
+
+var Variables = map[string]any{}
diff --git a/std/functions.go b/std/functions.go
index ab0e46a..7260244 100644
--- a/std/functions.go
+++ b/std/functions.go
@@ -1,12 +1,32 @@
package std
-import "fmt"
+import (
+ "fmt"
+ "github.com/Knetic/govaluate"
+)
var Functions = map[string]func(args ...interface{}) interface{}{
"print": func(args ...interface{}) interface{} {
fmt.Print(args...)
return nil
},
+ "math": func(args ...interface{}) interface{} {
+ if len(args) > 1 {
+ fmt.Println("math function takes 1 argument")
+ return nil
+ }
+ str, ok := args[0].(string)
+ if !ok {
+ fmt.Println("math function first argument must be a string")
+ return nil
+ }
+ output, err := ParseArithmeticExpressions(str)
+ if err != nil {
+ fmt.Println(err)
+ return nil
+ }
+ return output
+ },
"printf": func(args ...interface{}) interface{} {
if len(args) == 0 {
return ""
@@ -92,4 +112,41 @@ var Functions = map[string]func(args ...interface{}) interface{}{
return arg1 + arg2
},
+ "free": func(args ...interface{}) interface{} {
+ if len(args) > 1 {
+ fmt.Println("free function takes 1 argument")
+ return nil
+ }
+ str, ok := args[0].(string)
+ if !ok {
+ fmt.Println("free function first argument must be a string")
+ return nil
+ }
+ delete(Variables, str)
+ return nil
+ },
+}
+
+func ParseArithmeticExpressions(expression string) (any, error) {
+ // Create new expression with default token factory
+ expr, err := govaluate.NewEvaluableExpression(expression)
+ if err != nil {
+ return 0, fmt.Errorf("Error parsing expression: %v", err)
+ }
+
+ // Evaluate expression with empty parameter map
+ result, err := expr.Evaluate(nil)
+ if err != nil {
+ return 0, fmt.Errorf("Error evaluating expression: %v", err)
+ }
+
+ // Convert result to int and return
+
+ if result == true || result == false {
+ return result == "true", nil
+ }
+ if val, ok := result.(float64); ok {
+ return int(val), nil
+ }
+ return 0, fmt.Errorf("Error converting result to int")
}