This commit is contained in:
Marvin Blum
2015-10-25 13:04:30 +01:00
parent 276dd2c1e9
commit 2e7e198047
6 changed files with 317 additions and 317 deletions

View File

@@ -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
} }

View File

@@ -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"
} }
} }

View File

@@ -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()
} }
} }

View File

@@ -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
} }

View File

@@ -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)
} }

View File

@@ -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)
} }