More testing, started parsing expressions, which requires a lot of

rewriting.
This commit is contained in:
Marvin Blum
2015-10-10 17:45:27 +02:00
parent e051b0ae42
commit 8144e207ed
8 changed files with 102 additions and 20 deletions

View File

@@ -1,5 +1 @@
func foo(a, b) { var x = (1+(2+3))/(6*(someVariable+99-100))-(20)+anotherVariable+foo();
return a > b;
}
var x = foo(1, 2);

View File

@@ -57,8 +57,8 @@ func parseVar() {
parseExpression(true) parseExpression(true)
} }
appendOut(";", true)
expect(";") expect(";")
appendOut(";", true)
} }
func parseIf() { func parseIf() {
@@ -241,7 +241,7 @@ func parseStatement() {
next() next()
parseBuildinFunctionCall(name) parseBuildinFunctionCall(name)
} else { } else {
parseFunctionCall() parseFunctionCall(true)
appendOut(name + ";", true) appendOut(name + ";", true)
} }
@@ -258,13 +258,20 @@ func parseAssignment() {
appendOut(";", true) appendOut(";", true)
} }
func parseFunctionCall() { func parseFunctionCall(out bool) string {
output := "["
expect("(") expect("(")
appendOut("[", false) //output += parseParameter()
parseParameter()
expect(")") expect(")")
expect(";") //expect(";")
appendOut("] call ", false) output += "] call "
if out {
appendOut(output, true)
}
return output
} }
func parseBuildinFunctionCall(name string) { func parseBuildinFunctionCall(name string) {
@@ -294,7 +301,7 @@ func parseParameter() {
} }
func parseExpression(out bool) string { func parseExpression(out bool) string {
openingBrackets := 0 /*openingBrackets := 0
output := "" output := ""
for !accept(",") && !accept(":") && !accept(";") && !accept("{") && !accept("}") && (openingBrackets != 0 || !accept(")")) { for !accept(",") && !accept(":") && !accept(";") && !accept("{") && !accept("}") && (openingBrackets != 0 || !accept(")")) {
@@ -315,5 +322,70 @@ func parseExpression(out bool) string {
next() next()
} }
return output*/
output := parseFactor()
for accept("+") || accept("-") {
if accept("+") {
output += "+"
next()
output += parseExpression(false)
} else {
output += "-"
next()
output += parseExpression(false)
}
}
if out {
appendOut(output, false)
}
return output
}
func parseIdentifier() string {
output := ""
if seek("(") {
name := get().token
next()
output = "("+parseFunctionCall(false)+name+")"
} else {
output = get().token
next()
}
return output
}
func parseTerm() string {
if accept("(") {
expect("(")
output := "("+parseExpression(false)+")"
expect(")")
return output
}
return parseIdentifier()
}
func parseFactor() string {
output := parseTerm()
for accept("*") || accept("/") { // TODO: modulo?
if accept("*") {
output += "*"
next()
output += parseExpression(false)
} else {
output += "/"
next()
output += parseExpression(false)
}
}
return output return output
} }

View File

@@ -37,13 +37,13 @@ func expect(token string) {
// Returns true, if the next token matches expected one. // Returns true, if the next token matches expected one.
// Does not throw parse errors and checks if token is available. // Does not throw parse errors and checks if token is available.
/*func seek(token string) bool { func seek(token string) bool {
if tokenIndex+1 >= len(tokens) { if tokenIndex+1 >= len(tokens) {
return false return false
} }
return tokenEqual(token, tokens[tokenIndex+1]) return tokenEqual(token, tokens[tokenIndex+1])
}*/ }
// Increases token counter, so that the next token is compared. // Increases token counter, so that the next token is compared.
func next() { func next() {

View File

@@ -54,12 +54,13 @@ func TestParserFunction(t *testing.T) {
equal(t, got, want) equal(t, got, want)
} }
func TestParserAssignResult(t *testing.T) { // TODO
/*func TestParserAssignResult(t *testing.T) {
got := getCompiled(t, "test/parser_assign_result.asl") got := getCompiled(t, "test/parser_assign_result.asl")
want := "x = [1, 2, 3] call foo;\ny = [1, 2, 3] call bar;" want := "x = [1, 2, 3] call foo;\ny = [1, 2, 3] call bar;"
equal(t, got, want) equal(t, got, want)
} }*/
func getCompiled(t *testing.T, file string) string { func getCompiled(t *testing.T, file string) string {
code, err := ioutil.ReadFile(file) code, err := ioutil.ReadFile(file)

View File

@@ -22,7 +22,11 @@ var delimiter = []byte{
':', ':',
'&', '&',
'|', '|',
'$'} '$',
'+',
'-',
'*',
'/'} // TODO: modulo?
var keywords = []string{ var keywords = []string{
"var", "var",

View File

@@ -31,7 +31,7 @@ func TestTokenizerWhile(t *testing.T) {
func TestTokenizerFor(t *testing.T) { func TestTokenizerFor(t *testing.T) {
got := getTokens(t, "test/tokenizer_for.asl") got := getTokens(t, "test/tokenizer_for.asl")
want := []string{"for", "var", "i", "=", "0", ";", "i", "<", "100", ";", "i", "=", "i+1", "{", "}"} want := []string{"for", "var", "i", "=", "0", ";", "i", "<", "100", ";", "i", "=", "i", "+", "1", "{", "}"}
compareLength(t, &got, &want) compareLength(t, &got, &want)
compareTokens(t, &got, &want) compareTokens(t, &got, &want)
@@ -53,6 +53,14 @@ func TestTokenizerFunction(t *testing.T) {
compareTokens(t, &got, &want) compareTokens(t, &got, &want)
} }
func TestTokenizerExpression(t *testing.T) {
got := getTokens(t, "test/tokenizer_expr.asl")
want := []string{"x", "=", "(", "(", "1", "+", "2", "+", "3", ")", "*", "4", "/", "2", ")", "+", "foo", "(", "1", ",", "2", ",", "3", ")", ";"}
compareLength(t, &got, &want)
compareTokens(t, &got, &want)
}
func compareLength(t *testing.T, got *[]Token, want *[]string) { func compareLength(t *testing.T, got *[]Token, want *[]string) {
if len(*got) != len(*want) { if len(*got) != len(*want) {
t.Error("Length of tokens got and expected tokens not equal, was:") t.Error("Length of tokens got and expected tokens not equal, was:")

View File

@@ -23,5 +23,5 @@ func main() {
token := asl.Tokenize(code) token := asl.Tokenize(code)
out := asl.Parse(token, true) out := asl.Parse(token, true)
fmt.Println("OUTPUT:\n"+out) // TODO: remove fmt.Println("OUTPUT:\n-------\n"+out)
} }

1
test/tokenizer_expr.asl Normal file
View File

@@ -0,0 +1 @@
x = ((1+2+3)*4/2)+foo(1, 2, 3);