123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- package transpiler
- import "fmt"
- import "strconv"
- import "io"
- import "io/ioutil"
- import "../parser/syntax"
- import "../parser"
- type Tree = *parser.Tree
- type TransFunction = func(Tree, int) string
- var Rules = []map[string]TransFunction {
- RootMap, CommandMap, FunctionMap,
- TypeMap, OO_Map, ExpressionMap, LiteralMap,
- }
- var TransMapByName = make(map[string]TransFunction)
- var TransMap = make(map[syntax.Id]TransFunction)
- func Transpile (tree Tree, ptr int) string {
- // hash returned by Children() is of type map[string]int,
- // which will return 0 if non-existing key requested.
- // so we use -1 to indicate root node instead
- if ptr == 0 {
- panic("invalid usage of Transpile(): please use ptr=-1 for root node")
- }
- if ptr == -1 {
- ptr = 0
- }
- var id = tree.Nodes[ptr].Part.Id
- // fmt.Printf("transpile: %v\n", syntax.Id2Name[id])
- var f, exists = TransMap[id]
- if exists {
- return f(tree, ptr)
- } else {
- panic (
- fmt.Sprintf (
- "transpilation rule for %v does not exist",
- syntax.Id2Name[id],
- ),
- )
- }
- }
- func TranspileFirstChild (tree Tree, ptr int) string {
- var node = &tree.Nodes[ptr]
- if node.Length > 0 {
- return Transpile(tree, node.Children[0])
- } else {
- parser.PrintTreeNode(ptr, node)
- panic("unable to transpile first child: this node has no child")
- }
- }
- func TranspileLastChild (tree Tree, ptr int) string {
- var node = &tree.Nodes[ptr]
- if node.Length > 0 {
- return Transpile(tree, node.Children[node.Length-1])
- } else {
- parser.PrintTreeNode(ptr, node)
- panic("unable to transpile last child: this node has no child")
- }
- }
- func TranspileChild (child_name string) TransFunction {
- return func (tree Tree, ptr int) string {
- var id = syntax.Name2Id[child_name]
- var node = &tree.Nodes[ptr]
- for i := 0; i < node.Length; i++ {
- var child_ptr = node.Children[i]
- if tree.Nodes[child_ptr].Part.Id == id {
- return Transpile(tree, child_ptr)
- }
- }
- parser.PrintTreeNode(ptr, node)
- panic("unable to find " + child_name + " in this node")
- }
- }
- func Children (tree Tree, ptr int) map[string]int {
- var node = &tree.Nodes[ptr]
- var hash = make(map[string]int)
- for i := node.Length-1; i >= 0; i-- {
- // reversed loop: smaller index override bigger index
- var child_ptr = node.Children[i]
- var name = syntax.Id2Name[tree.Nodes[child_ptr].Part.Id]
- hash[name] = child_ptr
- }
- return hash
- }
- func GetFileName (tree Tree) string {
- return EscapeRawString([]rune(tree.File))
- }
- func GetRowColInfo (tree Tree, ptr int) (string, string) {
- var point = tree.Info[tree.Tokens[tree.Nodes[ptr].Pos].Pos]
- return strconv.Itoa(point.Row), strconv.Itoa(point.Col)
- }
- func TranspileFile (file io.Reader, name string, root string) string {
- var content, err = ioutil.ReadAll(file)
- if err != nil { panic(fmt.Sprintf("error reading %v: %v", name, err)) }
- var code = []rune(string(content))
- var tree = parser.BuildTree(root, code, name)
- return Transpile(&tree, -1)
- }
- func ApplyRules () {
- for _, item := range Rules {
- for key, value := range item {
- var _, exists = TransMapByName[key]
- if exists { panic("duplicate transpilation rule for " + key) }
- TransMapByName[key] = value
- }
- }
- }
- func Init () {
- ApplyRules()
- for name, value := range TransMapByName {
- TransMap[syntax.Name2Id[name]] = value
- }
- }
|