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