wsfmt.go: refactor

Refactor and cleanup of unused variables
Switch to string builder
Better error handling
Make printIdentifier account for the dot e.g. structName.fieldName
Fix formatting for negative numbers in a case statment
Rewrite array printing
Simplify newline printing
This commit is contained in:
lordwelch 2018-05-15 13:07:27 -07:00
parent 339abbae9a
commit d6c0a9e0ec

372
wsfmt.go
View File

@ -14,35 +14,42 @@ import (
type stateFn func(*Formatter) stateFn type stateFn func(*Formatter) stateFn
type FmtSettings struct{}
type Formatter struct { type Formatter struct {
l *lex.Lexer l *lex.Lexer
pToken lex.Item previousToken lex.Item
token lex.Item token lex.Item
nToken lex.Item nextToken lex.Item
state stateFn state stateFn
maxNewlines int maxNewlines int
newlineCount int newlineCount int
scopeLevel []int
tempScopeLevel int
eol, CASE bool
parenDepth int parenDepth int
Output strings.Builder
scopeLevel []int
// Each index is one scope deep delimited by braces or case statement.
// the number is how many 'soft' scopes deep it is resets to 1 on newline e.g. an if statement without braces
} }
var ( var (
blank = lex.Item{Pos: -1} blank = lex.Item{Pos: -1}
b []byte b []byte
err error fmtErr error
) )
func main() { func main() {
file, _ := os.Open(os.Args[1]) file, _ := os.Open(os.Args[1])
f := Format(nil, file) f := Format(file)
f.run() f.run()
fmt.Println(f.Output.String())
if fmtErr != nil {
os.Stdout.Sync()
fmt.Fprintln(os.Stderr, "\n", fmtErr)
os.Exit(1)
}
} }
func Format(typ *FmtSettings, text io.Reader) (f *Formatter) { func Format(text io.Reader) (f *Formatter) {
var err error
FILE := transform.NewReader(text, unicode.BOMOverride(unicode.UTF8.NewDecoder().Transformer)) FILE := transform.NewReader(text, unicode.BOMOverride(unicode.UTF8.NewDecoder().Transformer))
b, err = ioutil.ReadAll(FILE) b, err = ioutil.ReadAll(FILE)
if err != nil { if err != nil {
@ -51,19 +58,19 @@ func Format(typ *FmtSettings, text io.Reader) (f *Formatter) {
f = &Formatter{} f = &Formatter{}
f.l = lex.Lex("name", string(b)) f.l = lex.Lex("name", string(b))
f.maxNewlines = 3 f.maxNewlines = 3
f.nToken = blank f.nextToken = blank
return f return f
} }
func (f *Formatter) next() lex.Item { func (f *Formatter) next() lex.Item {
f.pToken = f.token f.previousToken = f.token
var temp lex.Item var temp lex.Item
if f.nToken == blank { if f.nextToken == blank {
temp = f.l.NextItem() temp = f.l.NextItem()
} else { } else {
temp = f.nToken temp = f.nextToken
f.nToken = blank f.nextToken = blank
} }
for ; temp.Typ == lex.ItemSpace || temp.Typ == lex.ItemNewline; temp = f.l.NextItem() { for ; temp.Typ == lex.ItemSpace || temp.Typ == lex.ItemNewline; temp = f.l.NextItem() {
} }
@ -73,7 +80,7 @@ func (f *Formatter) next() lex.Item {
} }
func (f *Formatter) peek() lex.Item { func (f *Formatter) peek() lex.Item {
if f.nToken == blank { if f.nextToken == blank {
temp := f.l.NextItem() temp := f.l.NextItem()
count := 0 count := 0
for ; temp.Typ == lex.ItemSpace || temp.Typ == lex.ItemNewline; temp = f.l.NextItem() { for ; temp.Typ == lex.ItemSpace || temp.Typ == lex.ItemNewline; temp = f.l.NextItem() {
@ -86,9 +93,9 @@ func (f *Formatter) peek() lex.Item {
} else { } else {
f.newlineCount = 3 f.newlineCount = 3
} }
f.nToken = temp f.nextToken = temp
} }
return f.nToken return f.nextToken
} }
func (f *Formatter) run() { func (f *Formatter) run() {
@ -97,13 +104,17 @@ func (f *Formatter) run() {
} }
} }
func errorf(format string, args ...interface{}) stateFn {
fmtErr = fmt.Errorf(format, args...)
return nil
}
func format(f *Formatter) stateFn { func format(f *Formatter) stateFn {
switch t := f.next().Typ; { switch t := f.next().Typ; {
case t == lex.ItemEOF: case t == lex.ItemEOF:
return nil return nil
case t == lex.ItemError: case t == lex.ItemError:
fmt.Print("error:", f.token.Val) return errorf("error: %s", f.token.Val)
return nil
case t == lex.ItemComment: case t == lex.ItemComment:
f.printComment() f.printComment()
case t == lex.ItemFunction: case t == lex.ItemFunction:
@ -111,10 +122,10 @@ func format(f *Formatter) stateFn {
case t == lex.ItemIf, t == lex.ItemWhile, t == lex.ItemFor, t == lex.ItemSwitch: case t == lex.ItemIf, t == lex.ItemWhile, t == lex.ItemFor, t == lex.ItemSwitch:
return formatConditional return formatConditional
case t == lex.ItemElse: case t == lex.ItemElse:
if f.pToken.Typ == lex.ItemRightBrace { if f.previousToken.Typ == lex.ItemRightBrace {
fmt.Printf(" else") f.Output.WriteString(" else")
} else { } else {
fmt.Print("else") f.Output.WriteString("else")
} }
if f.peek().Typ != lex.ItemLeftBrace && f.peek().Typ != lex.ItemIf { if f.peek().Typ != lex.ItemLeftBrace && f.peek().Typ != lex.ItemIf {
f.scopeLevel[len(f.scopeLevel)-1]++ f.scopeLevel[len(f.scopeLevel)-1]++
@ -122,9 +133,11 @@ func format(f *Formatter) stateFn {
printTab(f) printTab(f)
} }
case t == lex.ItemReturn: case t == lex.ItemReturn:
fmt.Printf("%s ", f.token.Val) f.Output.WriteString(f.token.Val + " ")
case t == lex.ItemModifiers, t == lex.ItemIdentifier, t == lex.ItemNumber, t == lex.ItemBool, t == lex.ItemString: case t == lex.ItemModifiers, t == lex.ItemIdentifier, t == lex.ItemNumber, t == lex.ItemBool, t == lex.ItemString:
printIdentifier(f) if !printIdentifier(f) {
return errorf("invalid identifier: trailing dot '.'")
}
case isChar(t): case isChar(t):
return printChar(f) return printChar(f)
case t == lex.ItemStruct: case t == lex.ItemStruct:
@ -134,74 +147,76 @@ func format(f *Formatter) stateFn {
case t == lex.ItemOperator: case t == lex.ItemOperator:
printOperator(f) printOperator(f)
case t == lex.ItemArray: case t == lex.ItemArray:
if !printArray(f) { return formatArray
return nil
}
case t == lex.ItemCase: case t == lex.ItemCase:
return formatCase return formatCase
case t == lex.ItemEnum: case t == lex.ItemEnum:
return formatEnum return formatEnum
default: default:
fmt.Fprintf(os.Stderr, "\nexpected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val) return errorf("expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
return nil
} }
return format return format
} }
func (f *Formatter) printComment() { func (f *Formatter) printComment() {
fmt.Printf("%s", f.token.Val) f.Output.WriteString(f.token.Val)
printNewline(f) printNewline(f)
} }
func formatFunction(f *Formatter) stateFn { func formatFunction(f *Formatter) stateFn {
if f.token.Typ == lex.ItemFunction { if f.token.Typ == lex.ItemFunction {
fmt.Printf("%s ", f.token.Val) f.Output.WriteString(f.token.Val + " ")
} }
switch t := f.next().Typ; { switch t := f.next().Typ; {
case t == lex.ItemEOF: case t == lex.ItemEOF:
fmt.Fprintf(os.Stderr, "unexpected EOF wanted identifier\n") return errorf("unexpected EOF wanted identifier\n")
return nil
case t == lex.ItemComment: case t == lex.ItemComment:
f.printComment() f.printComment()
case t == lex.ItemIdentifier: case t == lex.ItemIdentifier:
printIdentifier(f) if !printIdentifier(f) {
return errorf("invalid identifier: trailing dot '.'")
}
if f.next().Typ == lex.ItemLeftParen { if f.next().Typ == lex.ItemLeftParen {
printChar(f) printChar(f)
return format return format
} }
return errorf("expected left Parenthesis got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
} }
fmt.Print("\n") return errorf("expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
fmt.Fprintf(os.Stderr, "\nexpected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
return nil
// return formatFunction
} }
func formatStruct(f *Formatter) stateFn { func formatStruct(f *Formatter) stateFn {
if f.token.Typ == lex.ItemStruct { if f.token.Typ == lex.ItemStruct {
printIdentifier(f) if !printIdentifier(f) {
return errorf("invalid identifier: trailing dot '.'")
}
} }
switch t := f.next().Typ; { switch t := f.next().Typ; {
case t == lex.ItemEOF: case t == lex.ItemEOF:
fmt.Fprintf(os.Stderr, "unexpected EOF wanted identifier\n") return errorf("unexpected EOF wanted identifier\n")
return nil
case t == lex.ItemComment: case t == lex.ItemComment:
f.printComment() f.printComment()
case t == lex.ItemIdentifier: case t == lex.ItemIdentifier:
printIdentifier(f) if !printIdentifier(f) {
return errorf("invalid identifier: trailing dot '.'")
}
return format return format
default: default:
fmt.Fprintf(os.Stderr, "expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val) return errorf("expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
return nil
} }
return formatStruct return formatStruct
} }
func formatVar(f *Formatter) stateFn { func formatVar(f *Formatter) stateFn {
printIdentifier(f) if !printIdentifier(f) {
return errorf("invalid identifier: trailing dot '.'")
}
for notdone := true; notdone; { for notdone := true; notdone; {
if f.next().Typ == lex.ItemIdentifier { if f.next().Typ == lex.ItemIdentifier {
printIdentifier(f) if !printIdentifier(f) {
return errorf("invalid identifier: trailing dot '.'")
}
if f.next().Typ == lex.ItemChar { if f.next().Typ == lex.ItemChar {
switch f.token.Val { switch f.token.Val {
case ",": case ",":
@ -210,40 +225,53 @@ func formatVar(f *Formatter) stateFn {
printChar(f) printChar(f)
notdone = false notdone = false
default: default:
fmt.Fprintf(os.Stderr, "expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val) return errorf("expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
return nil
} }
} else { } else {
fmt.Fprintf(os.Stderr, "expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val) return errorf("expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
return nil
} }
} else { } else {
fmt.Fprintf(os.Stderr, "expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val) return errorf("expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
return nil
} }
} }
switch f.next().Typ { switch f.next().Typ {
case lex.ItemIdentifier: case lex.ItemIdentifier:
printIdentifier(f) if !printIdentifier(f) {
case lex.ItemArray: return errorf("invalid identifier: trailing dot '.'")
if !printArray(f) {
return nil
} }
case lex.ItemArray:
return formatArray // errorf("Bad array syntax")
default: default:
fmt.Fprintf(os.Stderr, "expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val) return errorf("expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
return nil
} }
return format return format
} }
func printIdentifier(f *Formatter) { func printIdentifier(f *Formatter) bool {
str := "%s" switch i := f.peek(); {
switch f.peek().Val { case i.Val == "{", i.Val == "}", i.Val == "(", i.Val == ")", i.Val == "[", i.Val == "]", i.Val == "|", i.Val == ",", i.Val == ":", i.Val == ";":
case "{", "}", "(", ")", "[", "]", "|", ",", ":", ";", ".": f.Output.WriteString(f.token.Val)
case i.Typ == lex.ItemDot:
f.Output.WriteString(f.token.Val)
f.next()
return printDot(f)
default: default:
str += " " f.Output.WriteString(f.token.Val + " ")
} }
fmt.Printf(str, f.token.Val) return true
}
func printDot(f *Formatter) bool {
f.Output.WriteString(".")
if f.peek().Typ == lex.ItemIdentifier {
f.next()
return printIdentifier(f)
}
return false
} }
func printOperator(f *Formatter) { func printOperator(f *Formatter) {
@ -251,49 +279,48 @@ func printOperator(f *Formatter) {
switch f.token.Val { switch f.token.Val {
case "|", "!": case "|", "!":
case "+", "-": case "+", "-":
switch f.pToken.Typ { switch f.previousToken.Typ {
case lex.ItemLeftParen, lex.ItemOperator, lex.ItemReturn: case lex.ItemLeftParen, lex.ItemOperator, lex.ItemReturn, lex.ItemCase:
default: default:
str += " " str = "%s "
} }
default: default:
str += " " str = "%s "
} }
switch f.pToken.Val { switch f.previousToken.Val {
case ")", "]": case ")", "]":
str = " " + str str = " " + str
} }
fmt.Printf(str, f.token.Val) f.Output.WriteString(fmt.Sprintf(str, f.token.Val))
} }
func formatConditional(f *Formatter) stateFn { func formatConditional(f *Formatter) stateFn {
switch f.token.Typ { switch f.token.Typ {
case lex.ItemIf, lex.ItemWhile, lex.ItemFor, lex.ItemSwitch: case lex.ItemIf, lex.ItemWhile, lex.ItemFor, lex.ItemSwitch:
tok := f.token.Val if f.previousToken.Typ == lex.ItemElse {
if f.pToken.Typ == lex.ItemElse { f.Output.WriteString(" ")
fmt.Print(" ")
} }
if f.next().Typ != lex.ItemLeftParen { if f.next().Typ != lex.ItemLeftParen {
fmt.Fprintf(os.Stderr, "expected parenthesis got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val) return errorf("expected parenthesis got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
return nil
} }
fmt.Printf("%s (", tok) f.Output.WriteString(f.previousToken.Val + " (")
f.parenDepth = 1 f.parenDepth = 1
} }
switch t := f.next().Typ; { switch t := f.next().Typ; {
case t == lex.ItemEOF: case t == lex.ItemEOF:
fmt.Fprintf(os.Stderr, "unexpected EOF wanted identifier\n") return errorf("unexpected EOF wanted identifier\n")
return nil
case t == lex.ItemComment: case t == lex.ItemComment:
f.printComment() f.printComment()
case t == lex.ItemOperator: case t == lex.ItemOperator:
printOperator(f) printOperator(f)
case t == lex.ItemIdentifier, t == lex.ItemNumber, t == lex.ItemString, t == lex.ItemBool: case t == lex.ItemIdentifier, t == lex.ItemNumber, t == lex.ItemString, t == lex.ItemBool:
printIdentifier(f) if !printIdentifier(f) {
return errorf("expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
}
case isChar(t): case isChar(t):
if f.token.Val == ";" { if f.token.Val == ";" {
fmt.Print("; ") f.Output.WriteString("; ")
} else { } else {
printChar(f) printChar(f)
} }
@ -319,10 +346,10 @@ func formatNewLine(f *Formatter) stateFn {
switch t := f.peek().Typ; { switch t := f.peek().Typ; {
case t == lex.ItemEOF: case t == lex.ItemEOF:
f.Output.WriteString("\n")
return nil return nil
case t == lex.ItemError: case t == lex.ItemError:
fmt.Print("error:", f.token.Val) return errorf("error: " + f.token.Val)
return nil
case t == lex.ItemCase: case t == lex.ItemCase:
printNewline(f) printNewline(f)
f.scopeLevel = f.scopeLevel[:len(f.scopeLevel)-1] f.scopeLevel = f.scopeLevel[:len(f.scopeLevel)-1]
@ -337,20 +364,21 @@ func formatNewLine(f *Formatter) stateFn {
} }
func formatEnum(f *Formatter) stateFn { func formatEnum(f *Formatter) stateFn {
printIdentifier(f) if !printIdentifier(f) {
if f.next().Typ != lex.ItemIdentifier { return errorf("invalid identifier: trailing dot '.'")
fmt.Fprintf(os.Stderr, "expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val) }
return nil if f.next().Typ != lex.ItemIdentifier {
return errorf("expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
}
if !printIdentifier(f) {
return errorf("expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
} }
printIdentifier(f)
if f.next().Typ != lex.ItemLeftBrace { if f.next().Typ != lex.ItemLeftBrace {
fmt.Fprintf(os.Stderr, "expected left brace got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val) return errorf("expected left brace got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
return nil
} }
f.scopeLevel = append(f.scopeLevel, 1) f.scopeLevel = append(f.scopeLevel, 1)
fmt.Print(" {") f.Output.WriteString(" {")
f.newlineCount = -1
printNewline(f) printNewline(f)
printTab(f) printTab(f)
return formatEnumIdent return formatEnumIdent
@ -358,20 +386,22 @@ func formatEnum(f *Formatter) stateFn {
func formatEnumIdent(f *Formatter) stateFn { func formatEnumIdent(f *Formatter) stateFn {
if f.next().Typ != lex.ItemIdentifier { if f.next().Typ != lex.ItemIdentifier {
fmt.Fprintf(os.Stderr, "expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val) return errorf("expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
return nil }
if !printIdentifier(f) {
return errorf("expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
} }
printIdentifier(f)
switch f.peek().Val { switch f.peek().Val {
case "=": case "=":
f.next() f.next()
printOperator(f) printOperator(f)
if f.peek().Typ != lex.ItemNumber { if f.peek().Typ != lex.ItemNumber {
fmt.Fprintf(os.Stderr, "expected Number got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val) return errorf("expected Number got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
return nil
} }
f.next() f.next()
printIdentifier(f) if !printIdentifier(f) {
return errorf("expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
}
if f.peek().Typ == lex.ItemRightBrace { if f.peek().Typ == lex.ItemRightBrace {
return format return format
} }
@ -383,11 +413,10 @@ func formatEnumIdent(f *Formatter) stateFn {
func formatEnumChar(f *Formatter) stateFn { func formatEnumChar(f *Formatter) stateFn {
if f.next().Val != "," { if f.next().Val != "," {
fmt.Fprintf(os.Stderr, "expected Comma got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val) return errorf("expected Comma got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
return nil
} }
fmt.Print(",") f.Output.WriteString(",")
if f.peek().Typ == lex.ItemRightBrace { if f.peek().Typ == lex.ItemRightBrace {
return format return format
} }
@ -398,95 +427,110 @@ func formatEnumChar(f *Formatter) stateFn {
func formatRightBrace(f *Formatter) stateFn { func formatRightBrace(f *Formatter) stateFn {
f.scopeLevel = f.scopeLevel[:len(f.scopeLevel)-1] f.scopeLevel = f.scopeLevel[:len(f.scopeLevel)-1]
if f.pToken.Typ != lex.ItemLeftBrace { if f.previousToken.Typ != lex.ItemLeftBrace {
fmt.Print("\n") f.Output.WriteString("\n")
printTab(f) printTab(f)
} }
fmt.Print("}") f.Output.WriteString("}")
switch f.peek().Typ { switch f.peek().Typ {
case lex.ItemChar, lex.ItemElse, lex.ItemRightBrace: case lex.ItemChar, lex.ItemElse, lex.ItemRightBrace:
return format return format
} }
return formatNewLine return formatNewLine
} }
func formatCase(f *Formatter) stateFn { func formatCase(f *Formatter) stateFn {
printIdentifier(f) if !printIdentifier(f) {
if !printCase(f) { return errorf("invalid identifier: trailing dot '.'")
return nil }
switch f.next().Typ {
case lex.ItemLeftParen:
f.Output.WriteString(" (")
if f.next().Typ != lex.ItemIdentifier || !printIdentifier(f) {
return errorf("expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
}
if f.next().Typ != lex.ItemRightParen {
return errorf("expected parenthesis got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
}
f.Output.WriteString(")")
if f.next().Typ != lex.ItemIdentifier || !printIdentifier(f) {
return errorf("expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
}
case lex.ItemIdentifier, lex.ItemNumber, lex.ItemString:
if !printIdentifier(f) {
return errorf("expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
}
case lex.ItemOperator:
if (f.token.Val == "+" || f.token.Val == "-") && f.peek().Typ == lex.ItemNumber {
printOperator(f)
f.next()
if !printIdentifier(f) {
return errorf("expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
}
} else {
return errorf("Invalid Operator got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
}
} }
if f.next().Val != ":" { if f.next().Val != ":" {
fmt.Fprintf(os.Stderr, "\nexpected \":\" got %s: %s %s\n", lex.Rkey[f.token.Typ], f.token.Val, f.pToken.Val) return errorf("expected \":\" got %s: %s %s\n", lex.Rkey[f.token.Typ], f.token.Val, f.previousToken.Val)
return nil
} }
fmt.Print(":") f.Output.WriteString(":")
f.scopeLevel = append(f.scopeLevel, 1) f.scopeLevel = append(f.scopeLevel, 1)
return formatNewLine return formatNewLine
} }
func printCase(f *Formatter) bool { func formatArray(f *Formatter) stateFn {
switch f.next().Typ {
case lex.ItemLeftParen:
fmt.Print(" (")
if f.next().Typ != lex.ItemIdentifier {
fmt.Fprintf(os.Stderr, "expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
return false
}
printIdentifier(f)
if f.next().Typ != lex.ItemRightParen {
fmt.Fprintf(os.Stderr, "expected parenthesis got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
return false
}
fmt.Print(")")
if f.next().Typ != lex.ItemIdentifier {
fmt.Fprintf(os.Stderr, "expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
return false
}
printIdentifier(f)
case lex.ItemIdentifier, lex.ItemNumber, lex.ItemString:
printIdentifier(f)
}
return true
}
func printArray(f *Formatter) bool {
if f.next().Val != "<" { if f.next().Val != "<" {
fmt.Fprintf(os.Stderr, "expected \"<\" got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val) return errorf("expected \"<\" got %s: %s %s\n", lex.Rkey[f.token.Typ], f.token.Val, f.previousToken.Val)
return false
} }
fmt.Printf("array<") f.Output.WriteString("array<")
switch f.next().Typ { switch f.next().Typ {
case lex.ItemIdentifier: case lex.ItemIdentifier:
fmt.Print(f.token.Val) for {
f.Output.WriteString(f.token.Val)
if f.peek().Typ != lex.ItemDot {
break
}
f.next()
f.Output.WriteString(".")
if f.peek().Typ != lex.ItemIdentifier {
return errorf("expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val)
}
f.next()
}
case lex.ItemArray: case lex.ItemArray:
printArray(f) return formatArray
default: default:
fmt.Fprintf(os.Stderr, "expected Identifier got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val) return errorf("Bad array syntax")
return false
} }
if f.next().Val != ">" { if f.next().Val != ">" {
fmt.Fprintf(os.Stderr, "expected \">\" got %s: %s\n", lex.Rkey[f.token.Typ], f.token.Val) return errorf("expected \">\" got %s: %s %s\n", lex.Rkey[f.token.Typ], f.token.Val, f.previousToken.Val)
return false
} }
fmt.Print(">") for f.peek(); f.nextToken.Val == ">"; {
return true f.next()
f.Output.WriteString(">")
}
if f.peek().Typ == lex.ItemOperator && f.peek().Val != ">" {
f.Output.WriteString("> ")
} else {
f.Output.WriteString(">")
}
return format
} }
func printTab(f *Formatter) { func printTab(f *Formatter) {
// fmt.Print(f.scopeLevel)
for _, t := range f.scopeLevel { for _, t := range f.scopeLevel {
for i := 0; i < t; i++ { for i := 0; i < t; i++ {
fmt.Print("\t") f.Output.WriteString("\t")
} }
} }
} }
func isChar(t lex.ItemType) bool { func isChar(t lex.ItemType) bool {
switch t { switch t {
case lex.ItemChar, lex.ItemLeftParen, lex.ItemRightParen, lex.ItemLeftBrace, lex.ItemRightBrace: case lex.ItemChar, lex.ItemLeftParen, lex.ItemRightParen, lex.ItemLeftBrace, lex.ItemRightBrace, lex.ItemDot:
return true return true
default: default:
return false return false
@ -496,40 +540,32 @@ func isChar(t lex.ItemType) bool {
func printChar(f *Formatter) stateFn { func printChar(f *Formatter) stateFn {
switch f.token.Val { switch f.token.Val {
case ":", ",": case ":", ",":
fmt.Printf("%s ", f.token.Val) f.Output.WriteString(f.token.Val + " ")
case ";": case ";":
fmt.Print(";") f.Output.WriteString(";")
if len(f.scopeLevel) > 0 { if len(f.scopeLevel) > 0 {
f.scopeLevel[len(f.scopeLevel)-1] = 1 f.scopeLevel[len(f.scopeLevel)-1] = 1
} }
return formatNewLine return formatNewLine
case "{": case "{":
fmt.Print(" {") f.Output.WriteString(" {")
f.scopeLevel = append(f.scopeLevel, 1) f.scopeLevel = append(f.scopeLevel, 1)
f.newlineCount = -1
return formatNewLine return formatNewLine
case "}": case "}":
return formatRightBrace return formatRightBrace
case ".":
printDot(f)
default: default:
fmt.Print(f.token.Val) f.Output.WriteString(f.token.Val)
} }
return format return format
} }
func printNewline(f *Formatter) { func printNewline(f *Formatter) {
if f.newlineCount == -1 {
f.peek() f.peek()
if f.newlineCount < 1 { if f.nextToken.Typ != lex.ItemEOF {
f.newlineCount = 1 for i := 0; i < f.newlineCount; i++ {
f.Output.WriteString("\n")
} }
} }
f.peek()
if f.nToken.Typ != lex.ItemEOF {
for i := 0; i < f.newlineCount-1; i++ {
fmt.Print("\n")
}
fmt.Print("\n")
} else {
fmt.Print("\n")
}
} }