mirror of
https://github.com/Kugelschieber/asl.git
synced 2026-01-18 12:00:25 +00:00
Added optional "pretty" printing.
This commit is contained in:
@@ -1 +1,5 @@
|
|||||||
|
func foo(a, b) {
|
||||||
|
return a > b;
|
||||||
|
}
|
||||||
|
|
||||||
var x = foo();
|
var x = foo();
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ const TAB = " "
|
|||||||
|
|
||||||
// Parses tokens, validates code to a specific degree
|
// Parses tokens, validates code to a specific degree
|
||||||
// and writes SQF code into desired location.
|
// and writes SQF code into desired location.
|
||||||
func Parse(token []Token) string {
|
func Parse(token []Token, prettyPrinting bool) string {
|
||||||
initParser(token)
|
initParser(token, prettyPrinting)
|
||||||
|
|
||||||
for tokenIndex < len(token) {
|
for tokenIndex < len(token) {
|
||||||
parseBlock()
|
parseBlock()
|
||||||
@@ -48,24 +48,24 @@ func parseBlock() {
|
|||||||
|
|
||||||
func parseVar() {
|
func parseVar() {
|
||||||
expect("var")
|
expect("var")
|
||||||
appendOut(get().token)
|
appendOut(get().token, false)
|
||||||
next()
|
next()
|
||||||
|
|
||||||
if accept("=") {
|
if accept("=") {
|
||||||
next()
|
next()
|
||||||
appendOut(" = ")
|
appendOut(" = ", false)
|
||||||
parseExpression(true)
|
parseExpression(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
appendOut(";\n")
|
appendOut(";", true)
|
||||||
expect(";")
|
expect(";")
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseIf() {
|
func parseIf() {
|
||||||
expect("if")
|
expect("if")
|
||||||
appendOut("if (")
|
appendOut("if (", false)
|
||||||
parseExpression(true)
|
parseExpression(true)
|
||||||
appendOut(") then {\n")
|
appendOut(") then {", true)
|
||||||
expect("{")
|
expect("{")
|
||||||
parseBlock()
|
parseBlock()
|
||||||
expect("}")
|
expect("}")
|
||||||
@@ -73,34 +73,34 @@ func parseIf() {
|
|||||||
if accept("else") {
|
if accept("else") {
|
||||||
next()
|
next()
|
||||||
expect("{")
|
expect("{")
|
||||||
appendOut("} else {\n")
|
appendOut("} else {", true)
|
||||||
parseBlock()
|
parseBlock()
|
||||||
expect("}")
|
expect("}")
|
||||||
}
|
}
|
||||||
|
|
||||||
appendOut("};\n")
|
appendOut("};", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseWhile() {
|
func parseWhile() {
|
||||||
expect("while")
|
expect("while")
|
||||||
appendOut("while {")
|
appendOut("while {", false)
|
||||||
parseExpression(true)
|
parseExpression(true)
|
||||||
appendOut("} do {\n")
|
appendOut("} do {", true)
|
||||||
expect("{")
|
expect("{")
|
||||||
parseBlock()
|
parseBlock()
|
||||||
expect("}")
|
expect("}")
|
||||||
appendOut("};\n")
|
appendOut("};", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseSwitch() {
|
func parseSwitch() {
|
||||||
expect("switch")
|
expect("switch")
|
||||||
appendOut("switch (")
|
appendOut("switch (", false)
|
||||||
parseExpression(true)
|
parseExpression(true)
|
||||||
appendOut(") do {\n")
|
appendOut(") do {", true)
|
||||||
expect("{")
|
expect("{")
|
||||||
parseSwitchBlock()
|
parseSwitchBlock()
|
||||||
expect("}")
|
expect("}")
|
||||||
appendOut("};\n")
|
appendOut("};", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseSwitchBlock() {
|
func parseSwitchBlock() {
|
||||||
@@ -110,25 +110,25 @@ func parseSwitchBlock() {
|
|||||||
|
|
||||||
if accept("case") {
|
if accept("case") {
|
||||||
expect("case")
|
expect("case")
|
||||||
appendOut("case ")
|
appendOut("case ", false)
|
||||||
parseExpression(true)
|
parseExpression(true)
|
||||||
expect(":")
|
expect(":")
|
||||||
appendOut(":\n")
|
appendOut(":", true)
|
||||||
|
|
||||||
if !accept("case") && !accept("}") {
|
if !accept("case") && !accept("}") {
|
||||||
appendOut("{\n")
|
appendOut("{", true)
|
||||||
parseBlock()
|
parseBlock()
|
||||||
appendOut("};\n")
|
appendOut("};", true)
|
||||||
}
|
}
|
||||||
} else if accept("default") {
|
} else if accept("default") {
|
||||||
expect("default")
|
expect("default")
|
||||||
expect(":")
|
expect(":")
|
||||||
appendOut("default:\n")
|
appendOut("default:", true)
|
||||||
|
|
||||||
if !accept("}") {
|
if !accept("}") {
|
||||||
appendOut("{\n")
|
appendOut("{", true)
|
||||||
parseBlock()
|
parseBlock()
|
||||||
appendOut("};\n")
|
appendOut("};", true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ func parseSwitchBlock() {
|
|||||||
|
|
||||||
func parseFor() {
|
func parseFor() {
|
||||||
expect("for")
|
expect("for")
|
||||||
appendOut("for [{")
|
appendOut("for [{", false)
|
||||||
|
|
||||||
// var in first assignment is optional
|
// var in first assignment is optional
|
||||||
if accept("var") {
|
if accept("var") {
|
||||||
@@ -146,32 +146,32 @@ func parseFor() {
|
|||||||
|
|
||||||
parseExpression(true)
|
parseExpression(true)
|
||||||
expect(";")
|
expect(";")
|
||||||
appendOut("}, {")
|
appendOut("}, {", false)
|
||||||
parseExpression(true)
|
parseExpression(true)
|
||||||
expect(";")
|
expect(";")
|
||||||
appendOut("}, {")
|
appendOut("}, {", false)
|
||||||
parseExpression(true)
|
parseExpression(true)
|
||||||
expect(";")
|
expect(";")
|
||||||
appendOut("}] do {\n")
|
appendOut("}] do {", true)
|
||||||
expect("{")
|
expect("{")
|
||||||
parseBlock()
|
parseBlock()
|
||||||
expect("}")
|
expect("}")
|
||||||
appendOut("};\n")
|
appendOut("};", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseForeach() {
|
func parseForeach() {
|
||||||
expect("each")
|
expect("each")
|
||||||
expr := parseExpression(false)
|
expr := parseExpression(false)
|
||||||
expect("{")
|
expect("{")
|
||||||
appendOut("{\n")
|
appendOut("{", true)
|
||||||
parseBlock()
|
parseBlock()
|
||||||
expect("}")
|
expect("}")
|
||||||
appendOut("} forEach (" + expr + ");\n")
|
appendOut("} forEach (" + expr + ");", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseFunction() {
|
func parseFunction() {
|
||||||
expect("func")
|
expect("func")
|
||||||
appendOut(get().token + " = {\n")
|
appendOut(get().token + " = {", true)
|
||||||
next()
|
next()
|
||||||
expect("(")
|
expect("(")
|
||||||
parseFunctionParameter()
|
parseFunctionParameter()
|
||||||
@@ -179,7 +179,7 @@ func parseFunction() {
|
|||||||
expect("{")
|
expect("{")
|
||||||
parseBlock()
|
parseBlock()
|
||||||
expect("}")
|
expect("}")
|
||||||
appendOut("};\n")
|
appendOut("};", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseFunctionParameter() {
|
func parseFunctionParameter() {
|
||||||
@@ -193,7 +193,7 @@ func parseFunctionParameter() {
|
|||||||
for !accept(")") {
|
for !accept(")") {
|
||||||
name := get().token
|
name := get().token
|
||||||
next()
|
next()
|
||||||
appendOut(name + " = _this select " + strconv.FormatInt(i, 10) + ";\n")
|
appendOut(name + " = _this select " + strconv.FormatInt(i, 10) + ";", true)
|
||||||
i++
|
i++
|
||||||
|
|
||||||
if !accept(")") {
|
if !accept(")") {
|
||||||
@@ -204,10 +204,10 @@ func parseFunctionParameter() {
|
|||||||
|
|
||||||
func parseReturn() {
|
func parseReturn() {
|
||||||
expect("return")
|
expect("return")
|
||||||
appendOut("return ")
|
appendOut("return ", false)
|
||||||
parseExpression(true)
|
parseExpression(true)
|
||||||
expect(";")
|
expect(";")
|
||||||
appendOut(";\n")
|
appendOut(";", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseSqf() {
|
func parseSqf() {
|
||||||
@@ -215,11 +215,11 @@ func parseSqf() {
|
|||||||
expect(":")
|
expect(":")
|
||||||
|
|
||||||
for !accept("sqf") {
|
for !accept("sqf") {
|
||||||
appendOut(get().token)
|
appendOut(get().token, false)
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
|
|
||||||
appendOut("\n")
|
appendOut("", true)
|
||||||
expect("sqf")
|
expect("sqf")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,7 +235,7 @@ func parseStatement() {
|
|||||||
next()
|
next()
|
||||||
|
|
||||||
if accept("=") {
|
if accept("=") {
|
||||||
appendOut(name)
|
appendOut(name, false)
|
||||||
parseAssignment()
|
parseAssignment()
|
||||||
} else if name == "$" {
|
} else if name == "$" {
|
||||||
name = get().token
|
name = get().token
|
||||||
@@ -243,7 +243,7 @@ func parseStatement() {
|
|||||||
parseBuildinFunctionCall(name)
|
parseBuildinFunctionCall(name)
|
||||||
} else {
|
} else {
|
||||||
parseFunctionCall()
|
parseFunctionCall()
|
||||||
appendOut(name + ";\n")
|
appendOut(name + ";", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !end() {
|
if !end() {
|
||||||
@@ -253,34 +253,34 @@ func parseStatement() {
|
|||||||
|
|
||||||
func parseAssignment() {
|
func parseAssignment() {
|
||||||
expect("=")
|
expect("=")
|
||||||
appendOut(" = " + get().token)
|
appendOut(" = " + get().token, false)
|
||||||
next()
|
next()
|
||||||
expect(";")
|
expect(";")
|
||||||
appendOut(";\n")
|
appendOut(";", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseFunctionCall() {
|
func parseFunctionCall() {
|
||||||
expect("(")
|
expect("(")
|
||||||
appendOut("[")
|
appendOut("[", false)
|
||||||
parseParameter()
|
parseParameter()
|
||||||
expect(")")
|
expect(")")
|
||||||
expect(";")
|
expect(";")
|
||||||
appendOut("] call ")
|
appendOut("] call ", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseBuildinFunctionCall(name string) {
|
func parseBuildinFunctionCall(name string) {
|
||||||
// FIXME: does not work for all kind of commands
|
// FIXME: does not work for all kind of commands
|
||||||
expect("(")
|
expect("(")
|
||||||
appendOut("[")
|
appendOut("[", false)
|
||||||
parseParameter()
|
parseParameter()
|
||||||
expect(")")
|
expect(")")
|
||||||
appendOut("] ")
|
appendOut("] ", false)
|
||||||
expect("(")
|
expect("(")
|
||||||
appendOut(name + " [")
|
appendOut(name + " [", false)
|
||||||
parseParameter()
|
parseParameter()
|
||||||
expect(")")
|
expect(")")
|
||||||
expect(";")
|
expect(";")
|
||||||
appendOut("];\n")
|
appendOut("];", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseParameter() {
|
func parseParameter() {
|
||||||
@@ -289,7 +289,7 @@ func parseParameter() {
|
|||||||
|
|
||||||
if !accept(")") {
|
if !accept(")") {
|
||||||
expect(",")
|
expect(",")
|
||||||
appendOut(", ")
|
appendOut(", ", false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -300,9 +300,9 @@ func parseExpression(out bool) string {
|
|||||||
|
|
||||||
for !accept(",") && !accept(":") && !accept(";") && !accept("{") && !accept("}") && (openingBrackets != 0 || !accept(")")) {
|
for !accept(",") && !accept(":") && !accept(";") && !accept("{") && !accept("}") && (openingBrackets != 0 || !accept(")")) {
|
||||||
current := get().token
|
current := get().token
|
||||||
|
|
||||||
if out {
|
if out {
|
||||||
appendOut(current)
|
appendOut(current, false)
|
||||||
} else {
|
} else {
|
||||||
output += current
|
output += current
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ var tokens []Token
|
|||||||
var tokenIndex int
|
var tokenIndex int
|
||||||
var out string
|
var out string
|
||||||
var offset int
|
var offset int
|
||||||
//var pretty bool
|
var pretty bool
|
||||||
|
|
||||||
// Initilizes the parser.
|
// Initilizes the parser.
|
||||||
func initParser(token []Token) {
|
func initParser(token []Token, prettyPrinting bool) {
|
||||||
if len(token) == 0 {
|
if len(token) == 0 {
|
||||||
panic("No tokens provided")
|
panic("No tokens provided")
|
||||||
}
|
}
|
||||||
@@ -16,6 +16,7 @@ func initParser(token []Token) {
|
|||||||
tokenIndex = 0
|
tokenIndex = 0
|
||||||
out = ""
|
out = ""
|
||||||
offset = 0
|
offset = 0
|
||||||
|
pretty = prettyPrinting
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true, if current token matches expected one.
|
// Returns true, if current token matches expected one.
|
||||||
@@ -36,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() {
|
||||||
@@ -69,6 +70,10 @@ 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) {
|
func appendOut(str string, newLine bool) {
|
||||||
out += str
|
out += str
|
||||||
|
|
||||||
|
if newLine && pretty {
|
||||||
|
out += "\n"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
5
src/asl/parser_test.go
Normal file
5
src/asl/parser_test.go
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package asl
|
||||||
|
|
||||||
|
import (
|
||||||
|
|
||||||
|
)
|
||||||
@@ -6,11 +6,15 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func usage() {
|
||||||
|
fmt.Println("Usage: asl [-v|-pretty]")
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// read test file
|
// read test file
|
||||||
code, _ := ioutil.ReadFile("in/simple.asl")
|
code, _ := ioutil.ReadFile("in/simple.asl")
|
||||||
token := asl.Tokenize(code)
|
token := asl.Tokenize(code)
|
||||||
out := asl.Parse(token)
|
out := asl.Parse(token, true)
|
||||||
|
|
||||||
fmt.Println("OUTPUT:\n"+out) // TODO: remove
|
fmt.Println("OUTPUT:\n"+out) // TODO: remove
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user