This repository has been archived on 2024-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
arf/parser/tree-tostring.go

455 lines
11 KiB
Go
Raw Normal View History

package parser
import "fmt"
import "sort"
import "git.tebibyte.media/arf/arf/lexer"
func doIndent (indent int, input ...string) (output string) {
for index := 0; index < indent; index ++ {
output += "\t"
}
for _, inputSection := range input {
output += inputSection
}
return
}
func sortMapKeysAlphabetically[KEY_TYPE any] (
unsortedMap map[string] KEY_TYPE,
) (
sortedKeys []string,
) {
sortedKeys = make([]string, len(unsortedMap))
index := 0
for key, _ := range unsortedMap {
sortedKeys[index] = key
index ++
}
sort.Strings(sortedKeys)
return
}
2022-09-04 17:55:47 -06:00
func (tree SyntaxTree) ToString (indent int) (output string) {
output += doIndent(indent, ":arf\n")
if tree.author != "" {
output += doIndent(indent, "author \"", tree.author, "\"\n")
}
if tree.license != "" {
output += doIndent(indent, "license \"", tree.license, "\"\n")
}
for _, require := range tree.requires {
output += doIndent(indent, "require \"", require, "\"\n")
}
output += doIndent(indent, "---\n")
sectionKeys := sortMapKeysAlphabetically(tree.sections)
for _, name := range sectionKeys {
output += tree.sections[name].ToString(indent)
}
return
}
func (identifier Identifier) ToString () (output string) {
for index, trailItem := range identifier.trail {
if index > 0 {
output += "."
}
output += trailItem
}
return
}
2022-09-15 20:43:02 -06:00
func (values ObjectDefaultValues) ToString (indent int) (output string) {
output += doIndent(indent, "(\n")
for name, value := range values {
output += doIndent (
indent,
name + ":" + value.ToString(indent, true))
}
output += doIndent(indent, ")\n")
2022-09-15 20:43:02 -06:00
return
}
func (values ArrayDefaultValues) ToString (indent int) (output string) {
output += doIndent(indent, "<\n")
for _, value := range values {
output += doIndent(indent, value.ToString(indent, true))
}
output += doIndent(indent, ">\n")
2022-09-15 20:43:02 -06:00
return
}
func (what Type) ToString (indent int) (output string) {
if what.kind == TypeKindBasic {
output += what.name.ToString()
} else {
output += "{"
2022-09-15 20:43:02 -06:00
output += what.points.ToString(indent)
2022-09-05 09:13:16 -06:00
if what.kind == TypeKindVariableArray {
2022-09-04 20:27:06 -06:00
output += " .."
}
output += "}"
}
2022-09-05 09:20:23 -06:00
if what.length > 1 {
2022-09-05 09:13:16 -06:00
output += fmt.Sprint(":", what.length)
}
if what.mutable {
output += ":mut"
}
2022-09-13 14:31:08 -06:00
2022-09-15 20:43:02 -06:00
if what.members != nil {
output += ":\n" + doIndent(indent, "(\n")
2022-09-15 20:43:02 -06:00
for _, member := range what.members {
output += doIndent (
indent, member.ToString(indent + 1), "\n")
2022-09-15 20:43:02 -06:00
}
output += doIndent(indent, ")")
2022-09-15 20:43:02 -06:00
}
defaultValueKind := what.defaultValue.kind
if defaultValueKind != ArgumentKindNil {
isComplexDefaultValue :=
defaultValueKind == ArgumentKindObjectDefaultValues ||
defaultValueKind == ArgumentKindArrayDefaultValues
if isComplexDefaultValue {
output += ":\n"
output += what.defaultValue.ToString(indent, true)
} else {
output += ":<"
output += what.defaultValue.ToString(indent, true)
output += ">\n"
2022-09-15 20:43:02 -06:00
}
}
return
}
2022-09-15 20:43:02 -06:00
func (declaration Declaration) ToString (indent int) (output string) {
output += declaration.name + ":"
2022-09-15 20:43:02 -06:00
output += declaration.what.ToString(indent)
return
}
2022-09-04 17:55:47 -06:00
func (argument Argument) ToString (indent int, breakLine bool) (output string) {
if !breakLine { indent = 0 }
2022-08-16 23:07:12 -06:00
if argument.kind == ArgumentKindNil {
output += "NIL-ARGUMENT"
if breakLine { output += "\n" }
return
}
switch argument.kind {
case ArgumentKindPhrase:
output += argument.value.(Phrase).ToString (
indent,
breakLine)
2022-09-15 20:43:02 -06:00
case ArgumentKindObjectDefaultValues:
output += argument.value.(ObjectDefaultValues).
ToString(indent)
if breakLine { output += "\n" }
2022-09-15 20:43:02 -06:00
case ArgumentKindArrayDefaultValues:
output += argument.value.(ArrayDefaultValues).
ToString(indent)
if breakLine { output += "\n" }
case ArgumentKindIdentifier:
output += doIndent (
indent,
argument.value.(Identifier).ToString())
if breakLine { output += "\n" }
case ArgumentKindDeclaration:
output += doIndent (
indent,
2022-09-15 20:43:02 -06:00
argument.value.(Declaration).ToString(indent))
if breakLine { output += "\n" }
case ArgumentKindInt, ArgumentKindUInt, ArgumentKindFloat:
output += doIndent(indent, fmt.Sprint(argument.value))
if breakLine { output += "\n" }
case ArgumentKindString:
output += doIndent (
indent,
"\"" + argument.value.(string) + "\"")
if breakLine { output += "\n" }
case ArgumentKindRune:
output += doIndent (
indent,
"'" + string(argument.value.(rune)) + "'")
if breakLine { output += "\n" }
case ArgumentKindOperator:
var stringValue string
switch argument.value.(lexer.TokenKind) {
2022-09-03 13:38:57 -06:00
case lexer.TokenKindColon:
stringValue = ":"
case lexer.TokenKindPlus:
stringValue = "+"
case lexer.TokenKindMinus:
stringValue = "-"
case lexer.TokenKindIncrement:
stringValue = "++"
case lexer.TokenKindDecrement:
stringValue = "--"
case lexer.TokenKindAsterisk:
stringValue = "*"
case lexer.TokenKindSlash:
stringValue = "/"
case lexer.TokenKindExclamation:
stringValue = "!"
case lexer.TokenKindPercent:
stringValue = "%"
case lexer.TokenKindPercentAssignment:
stringValue = "%="
case lexer.TokenKindTilde:
stringValue = "~"
case lexer.TokenKindTildeAssignment:
stringValue = "~="
2022-09-03 18:32:27 -06:00
case lexer.TokenKindAssignment:
stringValue = "="
2022-09-03 18:32:27 -06:00
case lexer.TokenKindEqualTo:
stringValue = "=="
case lexer.TokenKindNotEqualTo:
stringValue = "!="
case lexer.TokenKindLessThanEqualTo:
stringValue = "<="
case lexer.TokenKindLessThan:
stringValue = "<"
case lexer.TokenKindLShift:
stringValue = "<<"
case lexer.TokenKindLShiftAssignment:
stringValue = "<<="
case lexer.TokenKindGreaterThan:
stringValue = ">"
case lexer.TokenKindGreaterThanEqualTo:
stringValue = ">="
case lexer.TokenKindRShift:
stringValue = ">>"
case lexer.TokenKindRShiftAssignment:
stringValue = ">>="
case lexer.TokenKindBinaryOr:
stringValue = "|"
case lexer.TokenKindBinaryOrAssignment:
stringValue = "|="
case lexer.TokenKindLogicalOr:
stringValue = "||"
case lexer.TokenKindBinaryAnd:
stringValue = "&"
case lexer.TokenKindBinaryAndAssignment:
stringValue = "&="
case lexer.TokenKindLogicalAnd:
stringValue = "&&"
case lexer.TokenKindBinaryXor:
stringValue = "^"
case lexer.TokenKindBinaryXorAssignment:
stringValue = "^="
}
output += doIndent(indent, stringValue)
if breakLine { output += "\n" }
}
return
}
2022-09-04 17:55:47 -06:00
func (section DataSection) ToString (indent int) (output string) {
output += doIndent (
indent,
2022-09-12 13:27:29 -06:00
"type ",
section.permission.ToString(), " ",
section.name, ":",
2022-09-15 20:43:02 -06:00
section.what.ToString(indent), "\n")
return
}
2022-09-12 13:27:29 -06:00
func (member TypeMember) ToString (indent int) (output string) {
2022-08-19 01:03:36 -06:00
output += doIndent(indent)
output += member.permission.ToString() + " "
output += member.name + ":"
2022-09-15 20:43:02 -06:00
output += member.what.ToString(indent)
if member.bitWidth > 0 {
output += fmt.Sprint(" & ", member.bitWidth)
}
2022-09-12 13:27:29 -06:00
output += "\n"
return
}
2022-09-12 13:27:29 -06:00
func (section TypeSection) ToString (indent int) (output string) {
output += doIndent (
indent,
2022-09-12 13:27:29 -06:00
"type ",
section.permission.ToString(), " ",
section.name, ":",
2022-09-15 20:43:02 -06:00
section.what.ToString(indent), "\n")
return
}
2022-09-12 13:27:29 -06:00
2022-09-04 17:55:47 -06:00
func (section EnumSection) ToString (indent int) (output string) {
2022-08-21 00:40:04 -06:00
output += doIndent (
indent,
"enum ",
section.permission.ToString(), " ",
section.name, ":",
2022-09-15 20:43:02 -06:00
section.what.ToString(indent), "\n")
2022-08-21 00:40:04 -06:00
2022-08-23 23:16:44 -06:00
for _, member := range section.members {
output += doIndent(indent + 1, member.name)
2022-08-21 00:40:04 -06:00
isComplexInitialization :=
member.value.kind == ArgumentKindObjectDefaultValues ||
member.value.kind == ArgumentKindArrayDefaultValues
2022-08-21 00:40:04 -06:00
2022-08-23 23:16:44 -06:00
if member.value.value == nil {
2022-08-21 00:40:04 -06:00
output += "\n"
} else if isComplexInitialization {
output += "\n"
2022-08-23 23:16:44 -06:00
output += member.value.ToString(indent + 2, true)
2022-08-21 00:40:04 -06:00
} else {
2022-08-23 23:16:44 -06:00
output += " " + member.value.ToString(0, false)
2022-08-21 00:40:04 -06:00
output += "\n"
}
}
return
}
2022-08-23 11:54:44 -06:00
2022-09-04 17:55:47 -06:00
func (section FaceSection) ToString (indent int) (output string) {
2022-08-23 11:54:44 -06:00
output += doIndent (
indent,
"face ",
section.permission.ToString(), " ",
section.name, ":",
2022-08-24 16:57:07 -06:00
section.inherits.ToString(), "\n")
2022-08-23 11:54:44 -06:00
for _, name := range sortMapKeysAlphabetically(section.behaviors) {
behavior := section.behaviors[name]
output += behavior.ToString(indent + 1)
}
return
}
2022-09-04 17:55:47 -06:00
func (behavior FaceBehavior) ToString (indent int) (output string) {
2022-08-23 11:54:44 -06:00
output += doIndent(indent, behavior.name, "\n")
for _, inputItem := range behavior.inputs {
2022-09-15 20:43:02 -06:00
output += doIndent(indent + 1, "> ", inputItem.ToString(indent), "\n")
2022-08-23 11:54:44 -06:00
}
for _, outputItem := range behavior.outputs {
2022-09-15 20:43:02 -06:00
output += doIndent(indent + 1, "< ", outputItem.ToString(indent), "\n")
2022-08-23 11:54:44 -06:00
}
return
}
2022-09-02 00:36:14 -06:00
func (phrase Phrase) ToString (indent int, ownLine bool) (output string) {
if ownLine {
output += doIndent(indent)
}
var initializationValues Argument
2022-09-12 13:27:29 -06:00
var declaration Argument
output += "[" + phrase.command.ToString(0, false)
for _, argument := range phrase.arguments {
isInitializationValue :=
argument.kind == ArgumentKindObjectDefaultValues ||
argument.kind == ArgumentKindArrayDefaultValues
if isInitializationValue {
initializationValues = argument
2022-09-12 13:27:29 -06:00
} else if argument.kind == ArgumentKindDeclaration {
declaration = argument
} else {
output += " " + argument.ToString(0, false)
}
}
output += "]"
2022-09-05 09:49:19 -06:00
if len(phrase.returnees) > 0 {
output += " ->"
2022-09-05 09:49:19 -06:00
for _, returnItem := range phrase.returnees {
output += " " + returnItem.ToString(0, false)
}
}
if ownLine {
output += "\n"
2022-09-12 13:27:29 -06:00
// TODO: make = phrases special, have them carry a declaration
// and argument and nothing else. somehow.
for _, member := range declaration.value.(Declaration).what.members {
output += member.ToString(indent + 1)
}
if initializationValues.kind != ArgumentKindNil {
output += initializationValues.ToString(indent + 1, true)
}
output += phrase.block.ToString(indent + 1)
}
return
}
func (block Block) ToString (indent int) (output string) {
for _, phrase := range block {
output += phrase.ToString(indent, true)
}
return
}
func (funcOutput FuncOutput) ToString (indent int) (output string) {
2022-09-13 14:31:08 -06:00
output += doIndent (
indent + 1,
2022-09-15 20:43:02 -06:00
"< ", funcOutput.Declaration.ToString(indent), "\n")
return
}
2022-09-04 17:55:47 -06:00
func (section FuncSection) ToString (indent int) (output string) {
2022-09-02 00:36:14 -06:00
output += doIndent (
indent,
"func ",
section.permission.ToString(), " ",
section.name, "\n")
if section.receiver != nil {
output += doIndent (
indent + 1,
2022-09-15 20:43:02 -06:00
"@ ", section.receiver.ToString(indent), "\n")
2022-09-02 00:36:14 -06:00
}
for _, inputItem := range section.inputs {
2022-09-15 20:43:02 -06:00
output += doIndent(indent + 1, "> ", inputItem.ToString(indent), "\n")
2022-09-02 00:36:14 -06:00
}
for _, outputItem := range section.outputs {
output += outputItem.ToString(indent + 1)
2022-09-02 00:36:14 -06:00
}
output += doIndent(indent + 1, "---\n")
if section.external {
output += doIndent(indent + 1, "external\n")
}
output += section.root.ToString(indent + 1)
2022-09-02 00:36:14 -06:00
return
}