mirror of
https://github.com/Kugelschieber/asl.git
synced 2026-01-18 12:00:25 +00:00
go fmt.
This commit is contained in:
@@ -36,7 +36,7 @@ func parseBlock() {
|
|||||||
} else if accept("return") {
|
} else if accept("return") {
|
||||||
parseReturn()
|
parseReturn()
|
||||||
} else if accept("case") || accept("default") {
|
} else if accept("case") || accept("default") {
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
parseStatement()
|
parseStatement()
|
||||||
}
|
}
|
||||||
@@ -54,34 +54,34 @@ func parseVar() {
|
|||||||
if accept("=") {
|
if accept("=") {
|
||||||
next()
|
next()
|
||||||
appendOut(" = ", false)
|
appendOut(" = ", false)
|
||||||
|
|
||||||
if accept("[") {
|
if accept("[") {
|
||||||
parseArray()
|
parseArray()
|
||||||
} else {
|
} else {
|
||||||
parseExpression(true)
|
parseExpression(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(";")
|
expect(";")
|
||||||
appendOut(";", true)
|
appendOut(";", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseArray() {
|
func parseArray() {
|
||||||
expect("[")
|
expect("[")
|
||||||
appendOut("[", false)
|
appendOut("[", false)
|
||||||
|
|
||||||
if !accept("]") {
|
if !accept("]") {
|
||||||
parseExpression(true)
|
parseExpression(true)
|
||||||
|
|
||||||
for accept(",") {
|
for accept(",") {
|
||||||
next()
|
next()
|
||||||
appendOut(",", false)
|
appendOut(",", false)
|
||||||
parseExpression(true)
|
parseExpression(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expect("]")
|
expect("]")
|
||||||
appendOut("]", false)
|
appendOut("]", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseIf() {
|
func parseIf() {
|
||||||
@@ -188,12 +188,12 @@ func parseForeach() {
|
|||||||
appendOut("{", true)
|
appendOut("{", true)
|
||||||
parseBlock()
|
parseBlock()
|
||||||
expect("}")
|
expect("}")
|
||||||
appendOut("} forEach (" + expr + ");", true)
|
appendOut("} forEach ("+expr+");", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseFunction() {
|
func parseFunction() {
|
||||||
expect("func")
|
expect("func")
|
||||||
appendOut(get().token + " = {", true)
|
appendOut(get().token+" = {", true)
|
||||||
next()
|
next()
|
||||||
expect("(")
|
expect("(")
|
||||||
parseFunctionParameter()
|
parseFunctionParameter()
|
||||||
@@ -215,7 +215,7 @@ func parseFunctionParameter() {
|
|||||||
for !accept(")") {
|
for !accept(")") {
|
||||||
name := get().token
|
name := get().token
|
||||||
next()
|
next()
|
||||||
appendOut(name + " = _this select " + strconv.FormatInt(i, 10) + ";", true)
|
appendOut(name+" = _this select "+strconv.FormatInt(i, 10)+";", true)
|
||||||
i++
|
i++
|
||||||
|
|
||||||
if !accept(")") {
|
if !accept(")") {
|
||||||
@@ -266,46 +266,46 @@ func parseAssignment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func parseFunctionCall(out bool, name string) string {
|
func parseFunctionCall(out bool, name string) string {
|
||||||
output := ""
|
output := ""
|
||||||
|
|
||||||
expect("(")
|
expect("(")
|
||||||
leftParams, leftParamCount := parseParameter(false)
|
leftParams, leftParamCount := parseParameter(false)
|
||||||
expect(")")
|
expect(")")
|
||||||
|
|
||||||
if accept("(") {
|
if accept("(") {
|
||||||
// buildin function
|
// buildin function
|
||||||
next()
|
next()
|
||||||
rightParams, rightParamCount := parseParameter(false)
|
rightParams, rightParamCount := parseParameter(false)
|
||||||
expect(")")
|
expect(")")
|
||||||
|
|
||||||
if leftParamCount > 1 {
|
if leftParamCount > 1 {
|
||||||
leftParams = "["+leftParams+"]"
|
leftParams = "[" + leftParams + "]"
|
||||||
}
|
}
|
||||||
|
|
||||||
if rightParamCount > 1 {
|
if rightParamCount > 1 {
|
||||||
rightParams = "["+rightParams+"]"
|
rightParams = "[" + rightParams + "]"
|
||||||
}
|
}
|
||||||
|
|
||||||
if leftParamCount > 0 {
|
if leftParamCount > 0 {
|
||||||
output = leftParams+" "+name+" "+rightParams
|
output = leftParams + " " + name + " " + rightParams
|
||||||
} else {
|
} else {
|
||||||
output = name+" "+rightParams
|
output = name + " " + rightParams
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
output = "["+leftParams+"] call "+name
|
output = "[" + leftParams + "] call " + name
|
||||||
}
|
}
|
||||||
|
|
||||||
if out {
|
if out {
|
||||||
appendOut(output, false)
|
appendOut(output, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseParameter(out bool) (string, int) {
|
func parseParameter(out bool) (string, int) {
|
||||||
output := ""
|
output := ""
|
||||||
count := 0
|
count := 0
|
||||||
|
|
||||||
for !accept(")") {
|
for !accept(")") {
|
||||||
output += parseExpression(out)
|
output += parseExpression(out)
|
||||||
count++
|
count++
|
||||||
@@ -315,119 +315,119 @@ func parseParameter(out bool) (string, int) {
|
|||||||
output += ", "
|
output += ", "
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if out {
|
if out {
|
||||||
appendOut(output, false)
|
appendOut(output, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
return output, count
|
return output, count
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseExpression(out bool) string {
|
func parseExpression(out bool) string {
|
||||||
output := parseArith()
|
output := parseArith()
|
||||||
|
|
||||||
for accept("<") || accept(">") || accept("&") || accept("|") || accept("=") {
|
for accept("<") || accept(">") || accept("&") || accept("|") || accept("=") {
|
||||||
if accept("<") {
|
if accept("<") {
|
||||||
output += "<"
|
output += "<"
|
||||||
next()
|
next()
|
||||||
} else if accept(">") {
|
} else if accept(">") {
|
||||||
output += ">"
|
output += ">"
|
||||||
next()
|
next()
|
||||||
} else if accept("&") {
|
} else if accept("&") {
|
||||||
next()
|
next()
|
||||||
expect("&")
|
expect("&")
|
||||||
output += "&&"
|
output += "&&"
|
||||||
} else if accept("|") {
|
} else if accept("|") {
|
||||||
next()
|
next()
|
||||||
expect("|")
|
expect("|")
|
||||||
output += "||"
|
output += "||"
|
||||||
} else {
|
} else {
|
||||||
output += "="
|
output += "="
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
|
|
||||||
if accept("=") {
|
if accept("=") {
|
||||||
output += "="
|
output += "="
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
|
|
||||||
output += parseExpression(false)
|
output += parseExpression(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if out {
|
if out {
|
||||||
appendOut(output, false)
|
appendOut(output, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseIdentifier() string {
|
func parseIdentifier() string {
|
||||||
output := ""
|
output := ""
|
||||||
|
|
||||||
if seek("(") && !accept("!") && !accept("-") {
|
if seek("(") && !accept("!") && !accept("-") {
|
||||||
name := get().token
|
name := get().token
|
||||||
next()
|
next()
|
||||||
output = "("+parseFunctionCall(false, name)+")"
|
output = "(" + parseFunctionCall(false, name) + ")"
|
||||||
} else if accept("!") || accept("-") {
|
} else if accept("!") || accept("-") {
|
||||||
output = get().token
|
output = get().token
|
||||||
next()
|
next()
|
||||||
|
|
||||||
if !accept("(") {
|
if !accept("(") {
|
||||||
output += get().token
|
output += get().token
|
||||||
next()
|
next()
|
||||||
} else {
|
} else {
|
||||||
output += parseTerm()
|
output += parseTerm()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
output = get().token
|
output = get().token
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
|
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseTerm() string {
|
func parseTerm() string {
|
||||||
if accept("(") {
|
if accept("(") {
|
||||||
expect("(")
|
expect("(")
|
||||||
output := "("+parseExpression(false)+")"
|
output := "(" + parseExpression(false) + ")"
|
||||||
expect(")")
|
expect(")")
|
||||||
|
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
return parseIdentifier()
|
return parseIdentifier()
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseFactor() string {
|
func parseFactor() string {
|
||||||
output := parseTerm()
|
output := parseTerm()
|
||||||
|
|
||||||
for accept("*") || accept("/") { // TODO: modulo?
|
for accept("*") || accept("/") { // TODO: modulo?
|
||||||
if accept("*") {
|
if accept("*") {
|
||||||
output += "*"
|
output += "*"
|
||||||
} else {
|
} else {
|
||||||
output += "/"
|
output += "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
next()
|
next()
|
||||||
output += parseExpression(false)
|
output += parseExpression(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseArith() string {
|
func parseArith() string {
|
||||||
output := parseFactor()
|
output := parseFactor()
|
||||||
|
|
||||||
for accept("+") || accept("-") {
|
for accept("+") || accept("-") {
|
||||||
if accept("+") {
|
if accept("+") {
|
||||||
output += "+"
|
output += "+"
|
||||||
} else {
|
} else {
|
||||||
output += "-"
|
output += "-"
|
||||||
}
|
}
|
||||||
|
|
||||||
next()
|
next()
|
||||||
output += parseExpression(false)
|
output += parseExpression(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,11 +38,11 @@ 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.
|
||||||
@@ -72,8 +72,8 @@ func tokenEqual(a string, b Token) bool {
|
|||||||
// Appends the output string to current SQF code output.
|
// Appends the output string to current SQF code output.
|
||||||
func appendOut(str string, newLine bool) {
|
func appendOut(str string, newLine bool) {
|
||||||
out += str
|
out += str
|
||||||
|
|
||||||
if newLine && pretty {
|
if newLine && pretty {
|
||||||
out += "\n"
|
out += "\n"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,118 +1,118 @@
|
|||||||
package asl_test
|
package asl_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"asl"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"asl"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestParserDeclaration(t *testing.T) {
|
func TestParserDeclaration(t *testing.T) {
|
||||||
got := getCompiled(t, "test/tokenizer_var.asl")
|
got := getCompiled(t, "test/tokenizer_var.asl")
|
||||||
want := "x = 1;\narray = [1,2,3];\n"
|
want := "x = 1;\narray = [1,2,3];\n"
|
||||||
|
|
||||||
equal(t, got, want)
|
equal(t, got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParserAssignment(t *testing.T) {
|
func TestParserAssignment(t *testing.T) {
|
||||||
got := getCompiled(t, "test/parser_assignment.asl")
|
got := getCompiled(t, "test/parser_assignment.asl")
|
||||||
want := "x = 1;\n"
|
want := "x = 1;\n"
|
||||||
|
|
||||||
equal(t, got, want)
|
equal(t, got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParserIf(t *testing.T) {
|
func TestParserIf(t *testing.T) {
|
||||||
got := getCompiled(t, "test/tokenizer_if.asl")
|
got := getCompiled(t, "test/tokenizer_if.asl")
|
||||||
want := "if (a<b) then {\n};\n"
|
want := "if (a<b) then {\n};\n"
|
||||||
|
|
||||||
equal(t, got, want)
|
equal(t, got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParserWhile(t *testing.T) {
|
func TestParserWhile(t *testing.T) {
|
||||||
got := getCompiled(t, "test/tokenizer_while.asl")
|
got := getCompiled(t, "test/tokenizer_while.asl")
|
||||||
want := "while {true} do {\n};"
|
want := "while {true} do {\n};"
|
||||||
|
|
||||||
equal(t, got, want)
|
equal(t, got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParserFor(t *testing.T) {
|
func TestParserFor(t *testing.T) {
|
||||||
got := getCompiled(t, "test/tokenizer_for.asl")
|
got := getCompiled(t, "test/tokenizer_for.asl")
|
||||||
want := "for [{i=0}, {i<100}, {i=i+1}] do {\n};\n"
|
want := "for [{i=0}, {i<100}, {i=i+1}] do {\n};\n"
|
||||||
|
|
||||||
equal(t, got, want)
|
equal(t, got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParserForeach(t *testing.T) {
|
func TestParserForeach(t *testing.T) {
|
||||||
got := getCompiled(t, "test/tokenizer_foreach.asl")
|
got := getCompiled(t, "test/tokenizer_foreach.asl")
|
||||||
want := "{\n} forEach (allUnits);\n"
|
want := "{\n} forEach (allUnits);\n"
|
||||||
|
|
||||||
equal(t, got, want)
|
equal(t, got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParserSwitch(t *testing.T) {
|
func TestParserSwitch(t *testing.T) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParserFunction(t *testing.T) {
|
func TestParserFunction(t *testing.T) {
|
||||||
got := getCompiled(t, "test/tokenizer_func.asl")
|
got := getCompiled(t, "test/tokenizer_func.asl")
|
||||||
want := "TestFunction = {\nparam0 = _this select 0;\nparam1 = _this select 1;\nreturn true;\n};\n"
|
want := "TestFunction = {\nparam0 = _this select 0;\nparam1 = _this select 1;\nreturn true;\n};\n"
|
||||||
|
|
||||||
equal(t, got, want)
|
equal(t, got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParserAssignResult(t *testing.T) {
|
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);\n"
|
want := "x = ([1, 2, 3] call foo);\ny = ([1, 2, 3] call bar);\n"
|
||||||
|
|
||||||
equal(t, got, want)
|
equal(t, got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParserExpression(t *testing.T) {
|
func TestParserExpression(t *testing.T) {
|
||||||
got := getCompiled(t, "test/parser_expression.asl")
|
got := getCompiled(t, "test/parser_expression.asl")
|
||||||
want := "x = -(1+(2+3))/(6*(someVariable+99-100))-(20)+!anotherVariable+([] call foo);\n"
|
want := "x = -(1+(2+3))/(6*(someVariable+99-100))-(20)+!anotherVariable+([] call foo);\n"
|
||||||
|
|
||||||
equal(t, got, want)
|
equal(t, got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParserExpression2(t *testing.T) {
|
func TestParserExpression2(t *testing.T) {
|
||||||
got := getCompiled(t, "test/parser_expression2.asl")
|
got := getCompiled(t, "test/parser_expression2.asl")
|
||||||
want := "x = true||(3>=4&&5<8);\n"
|
want := "x = true||(3>=4&&5<8);\n"
|
||||||
|
|
||||||
equal(t, got, want)
|
equal(t, got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParserFunctionCall(t *testing.T) {
|
func TestParserFunctionCall(t *testing.T) {
|
||||||
got := getCompiled(t, "test/parser_func_call.asl")
|
got := getCompiled(t, "test/parser_func_call.asl")
|
||||||
want := "myFunc = {\na = _this select 0;\nb = _this select 1;\nreturn a>b;\n};\n[1+3/4, 2-(66*22)/3-((123))] call myFunc;\n"
|
want := "myFunc = {\na = _this select 0;\nb = _this select 1;\nreturn a>b;\n};\n[1+3/4, 2-(66*22)/3-((123))] call myFunc;\n"
|
||||||
|
|
||||||
equal(t, got, want)
|
equal(t, got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParserBuildinFunctionCall(t *testing.T) {
|
func TestParserBuildinFunctionCall(t *testing.T) {
|
||||||
got := getCompiled(t, "test/parser_buildin_func.asl")
|
got := getCompiled(t, "test/parser_buildin_func.asl")
|
||||||
want := "_x = (([player, foo] getVar bar) setHit [\"head\", \"tail\"]);\n"
|
want := "_x = (([player, foo] getVar bar) setHit [\"head\", \"tail\"]);\n"
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("Could not read test file: "+file)
|
t.Error("Could not read test file: " + file)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens := asl.Tokenize(code)
|
tokens := asl.Tokenize(code)
|
||||||
|
|
||||||
return asl.Parse(tokens, true)
|
return asl.Parse(tokens, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func equal(t *testing.T, got, want string) {
|
func equal(t *testing.T, got, want string) {
|
||||||
if got != want {
|
if got != want {
|
||||||
t.Error("Results do not equal, got:")
|
t.Error("Results do not equal, got:")
|
||||||
t.Log(got)
|
t.Log(got)
|
||||||
t.Log("expected:")
|
t.Log("expected:")
|
||||||
t.Log(want)
|
t.Log(want)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,43 +52,43 @@ func Tokenize(code []byte) []Token {
|
|||||||
code = removeComments(code)
|
code = removeComments(code)
|
||||||
tokens := make([]Token, 0)
|
tokens := make([]Token, 0)
|
||||||
token, mask, isstring := "", false, false
|
token, mask, isstring := "", false, false
|
||||||
|
|
||||||
for i := range code {
|
for i := range code {
|
||||||
c := code[i]
|
c := code[i]
|
||||||
|
|
||||||
// string masks (backslash)
|
// string masks (backslash)
|
||||||
if c == '\\' && !mask {
|
if c == '\\' && !mask {
|
||||||
token += "\\"
|
token += "\\"
|
||||||
mask = true
|
mask = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// string
|
// string
|
||||||
if c == '"' && !mask {
|
if c == '"' && !mask {
|
||||||
token += "\""
|
token += "\""
|
||||||
isstring = !isstring
|
isstring = !isstring
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if isstring {
|
if isstring {
|
||||||
token += string(c)
|
token += string(c)
|
||||||
} else {
|
} else {
|
||||||
// delimeter, keyword or variable/expression
|
// delimeter, keyword or variable/expression
|
||||||
if byteArrayContains(delimiter, c) {
|
if byteArrayContains(delimiter, c) {
|
||||||
if token != "" {
|
if token != "" {
|
||||||
tokens = append(tokens, Token{token})
|
tokens = append(tokens, Token{token})
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens = append(tokens, Token{string(c)})
|
tokens = append(tokens, Token{string(c)})
|
||||||
token = ""
|
token = ""
|
||||||
} else if stringArrayContains(keywords, strings.ToLower(token)) && !isIdentifierCharacter(c) {
|
} else if stringArrayContains(keywords, strings.ToLower(token)) && !isIdentifierCharacter(c) {
|
||||||
tokens = append(tokens, Token{token})
|
tokens = append(tokens, Token{token})
|
||||||
token = ""
|
token = ""
|
||||||
} else if !byteArrayContains(whitespace, c) {
|
} else if !byteArrayContains(whitespace, c) {
|
||||||
token += string(c)
|
token += string(c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mask = false
|
mask = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,26 +104,26 @@ func removeComments(code []byte) []byte {
|
|||||||
|
|
||||||
for i := 0; i < len(code); i++ {
|
for i := 0; i < len(code); i++ {
|
||||||
c := code[i]
|
c := code[i]
|
||||||
|
|
||||||
// do not remove comments from strings
|
// do not remove comments from strings
|
||||||
if c == '\\' && !mask {
|
if c == '\\' && !mask {
|
||||||
mask = true
|
mask = true
|
||||||
}
|
|
||||||
|
|
||||||
if c == '"' && !mask {
|
|
||||||
isstring = !isstring
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// single/multi line comment
|
if c == '"' && !mask {
|
||||||
if !isstring {
|
isstring = !isstring
|
||||||
if c == '/' && nextChar(code, i) == '/' {
|
}
|
||||||
i = skipSingleLineComment(code, i+1)
|
|
||||||
continue
|
// single/multi line comment
|
||||||
} else if c == '/' && nextChar(code, i) == '*' {
|
if !isstring {
|
||||||
i = skipMultiLineComment(code, i+1)
|
if c == '/' && nextChar(code, i) == '/' {
|
||||||
continue
|
i = skipSingleLineComment(code, i+1)
|
||||||
}
|
continue
|
||||||
}
|
} else if c == '/' && nextChar(code, i) == '*' {
|
||||||
|
i = skipMultiLineComment(code, i+1)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
newcode[j] = c
|
newcode[j] = c
|
||||||
j++
|
j++
|
||||||
@@ -187,11 +187,11 @@ func stringArrayContains(haystack []string, needle string) bool {
|
|||||||
|
|
||||||
// Checks if a character is allowed for identifiers.
|
// Checks if a character is allowed for identifiers.
|
||||||
func isIdentifierCharacter(c byte) bool {
|
func isIdentifierCharacter(c byte) bool {
|
||||||
for i := range identifier {
|
for i := range identifier {
|
||||||
if identifier[i] == c {
|
if identifier[i] == c {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +1,52 @@
|
|||||||
package asl
|
package asl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"io/ioutil"
|
||||||
"io/ioutil"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTokenizerVar(t *testing.T) {
|
func TestTokenizerVar(t *testing.T) {
|
||||||
got := getTokens(t, "test/tokenizer_var.asl")
|
got := getTokens(t, "test/tokenizer_var.asl")
|
||||||
want := []string{"var", "x", "=", "1", ";", "var", "array", "=", "[", "1", ",", "2", ",", "3", "]", ";"}
|
want := []string{"var", "x", "=", "1", ";", "var", "array", "=", "[", "1", ",", "2", ",", "3", "]", ";"}
|
||||||
|
|
||||||
compareLength(t, &got, &want)
|
compareLength(t, &got, &want)
|
||||||
compareTokens(t, &got, &want)
|
compareTokens(t, &got, &want)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTokenizerIf(t *testing.T) {
|
func TestTokenizerIf(t *testing.T) {
|
||||||
got := getTokens(t, "test/tokenizer_if.asl")
|
got := getTokens(t, "test/tokenizer_if.asl")
|
||||||
want := []string{"if", "a", "<", "b", "{", "}"}
|
want := []string{"if", "a", "<", "b", "{", "}"}
|
||||||
|
|
||||||
compareLength(t, &got, &want)
|
compareLength(t, &got, &want)
|
||||||
compareTokens(t, &got, &want)
|
compareTokens(t, &got, &want)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTokenizerWhile(t *testing.T) {
|
func TestTokenizerWhile(t *testing.T) {
|
||||||
got := getTokens(t, "test/tokenizer_while.asl")
|
got := getTokens(t, "test/tokenizer_while.asl")
|
||||||
want := []string{"while", "true", "{", "}"}
|
want := []string{"while", "true", "{", "}"}
|
||||||
|
|
||||||
compareLength(t, &got, &want)
|
compareLength(t, &got, &want)
|
||||||
compareTokens(t, &got, &want)
|
compareTokens(t, &got, &want)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTokenizerForach(t *testing.T) {
|
func TestTokenizerForach(t *testing.T) {
|
||||||
got := getTokens(t, "test/tokenizer_foreach.asl")
|
got := getTokens(t, "test/tokenizer_foreach.asl")
|
||||||
want := []string{"foreach", "allUnits", "{", "}"}
|
want := []string{"foreach", "allUnits", "{", "}"}
|
||||||
|
|
||||||
compareLength(t, &got, &want)
|
compareLength(t, &got, &want)
|
||||||
compareTokens(t, &got, &want)
|
compareTokens(t, &got, &want)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTokenizerSwitch(t *testing.T) {
|
func TestTokenizerSwitch(t *testing.T) {
|
||||||
got := getTokens(t, "test/tokenizer_switch.asl")
|
got := getTokens(t, "test/tokenizer_switch.asl")
|
||||||
want := []string{"switch", "x", "{", "case", "1", ":", "x", "=", "1", ";", "break", ";", "case", "2", ":", "x", "=", "2", ";", "break", ";", "default", ":", "x", "=", "3", ";", "}"}
|
want := []string{"switch", "x", "{", "case", "1", ":", "x", "=", "1", ";", "break", ";", "case", "2", ":", "x", "=", "2", ";", "break", ";", "default", ":", "x", "=", "3", ";", "}"}
|
||||||
|
|
||||||
compareLength(t, &got, &want)
|
compareLength(t, &got, &want)
|
||||||
@@ -54,64 +54,64 @@ func TestTokenizerSwitch(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTokenizerFunction(t *testing.T) {
|
func TestTokenizerFunction(t *testing.T) {
|
||||||
got := getTokens(t, "test/tokenizer_func.asl")
|
got := getTokens(t, "test/tokenizer_func.asl")
|
||||||
want := []string{"func", "TestFunction", "(", "param0", ",", "param1", ")", "{", "return", "true", ";", "}"}
|
want := []string{"func", "TestFunction", "(", "param0", ",", "param1", ")", "{", "return", "true", ";", "}"}
|
||||||
|
|
||||||
compareLength(t, &got, &want)
|
compareLength(t, &got, &want)
|
||||||
compareTokens(t, &got, &want)
|
compareTokens(t, &got, &want)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTokenizerExpression(t *testing.T) {
|
func TestTokenizerExpression(t *testing.T) {
|
||||||
got := getTokens(t, "test/tokenizer_expr.asl")
|
got := getTokens(t, "test/tokenizer_expr.asl")
|
||||||
want := []string{"x", "=", "(", "(", "1", "+", "2", "+", "3", ")", "*", "4", "/", "2", ")", "+", "foo", "(", "1", ",", "2", ",", "3", ")", ";"}
|
want := []string{"x", "=", "(", "(", "1", "+", "2", "+", "3", ")", "*", "4", "/", "2", ")", "+", "foo", "(", "1", ",", "2", ",", "3", ")", ";"}
|
||||||
|
|
||||||
compareLength(t, &got, &want)
|
compareLength(t, &got, &want)
|
||||||
compareTokens(t, &got, &want)
|
compareTokens(t, &got, &want)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTokenizerIdentifier(t *testing.T) {
|
func TestTokenizerIdentifier(t *testing.T) {
|
||||||
got := getTokens(t, "test/tokenizer_identifier.asl")
|
got := getTokens(t, "test/tokenizer_identifier.asl")
|
||||||
want := []string{"var", "format", "=", "\"should not be for mat!\"", ";"}
|
want := []string{"var", "format", "=", "\"should not be for mat!\"", ";"}
|
||||||
|
|
||||||
compareLength(t, &got, &want)
|
compareLength(t, &got, &want)
|
||||||
compareTokens(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:")
|
||||||
gotlist, wantlist := "", ""
|
gotlist, wantlist := "", ""
|
||||||
|
|
||||||
for i := range *got {
|
for i := range *got {
|
||||||
gotlist += (*got)[i].token+" "
|
gotlist += (*got)[i].token + " "
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range *want {
|
for i := range *want {
|
||||||
wantlist += (*want)[i]+" "
|
wantlist += (*want)[i] + " "
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Log(gotlist)
|
t.Log(gotlist)
|
||||||
t.Log("expected:")
|
t.Log("expected:")
|
||||||
t.Log(wantlist)
|
t.Log(wantlist)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func compareTokens(t *testing.T, got *[]Token, want *[]string) {
|
func compareTokens(t *testing.T, got *[]Token, want *[]string) {
|
||||||
for i := range *got {
|
for i := range *got {
|
||||||
if (*got)[i].token != (*want)[i] {
|
if (*got)[i].token != (*want)[i] {
|
||||||
t.Error("Tokens do not match: "+(*got)[i].token+" != "+(*want)[i])
|
t.Error("Tokens do not match: " + (*got)[i].token + " != " + (*want)[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTokens(t *testing.T, file string) []Token {
|
func getTokens(t *testing.T, file string) []Token {
|
||||||
code, err := ioutil.ReadFile(file)
|
code, err := ioutil.ReadFile(file)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("Could not read test file: "+file)
|
t.Error("Could not read test file: " + file)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
return Tokenize(code)
|
return Tokenize(code)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ import (
|
|||||||
const version = "0.1"
|
const version = "0.1"
|
||||||
|
|
||||||
func usage() {
|
func usage() {
|
||||||
fmt.Println("Usage: asl [-v|-r|-pretty] <input file/folder> [<output file/folder>]\n")
|
fmt.Println("Usage: asl [-v|-r|-pretty] <input file/folder> [<output file/folder>]\n")
|
||||||
fmt.Println("-v (optional) shows asl version")
|
fmt.Println("-v (optional) shows asl version")
|
||||||
fmt.Println("-r (optional) recursivly compile all asl files in folder")
|
fmt.Println("-r (optional) recursivly compile all asl files in folder")
|
||||||
fmt.Println("-pretty (optional) activates pretty printing\n")
|
fmt.Println("-pretty (optional) activates pretty printing\n")
|
||||||
fmt.Println("<input file/folder> file or directory to compile")
|
fmt.Println("<input file/folder> file or directory to compile")
|
||||||
fmt.Println("<output file/folder> (optional) output file/folder, if not set, files will be created alongside their asl files")
|
fmt.Println("<output file/folder> (optional) output file/folder, if not set, files will be created alongside their asl files")
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -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.Print("OUTPUT:\n-------\n"+out)
|
fmt.Print("OUTPUT:\n-------\n" + out)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user