1
0
Эх сурвалжийг харах

заложил загрузку sexpr в ast

Пётр 9 жил өмнө
parent
commit
46ad6e1144

+ 5 - 2
gen/impl/sexpr/sexpr.go

@@ -25,12 +25,14 @@ type wr struct {
 	base  io.Writer
 	base  io.Writer
 	opts  gen.Opts
 	opts  gen.Opts
 	depth int
 	depth int
+	line  int
 }
 }
 
 
 func (w *wr) Ln() {
 func (w *wr) Ln() {
-	if w.opts.PrettyPrint {
+	if w.opts.PrettyPrint && w.line >= 0 {
 		w.base.Write([]byte("\n"))
 		w.base.Write([]byte("\n"))
 	}
 	}
+	w.line++
 }
 }
 
 
 func (w *wr) Tab() {
 func (w *wr) Tab() {
@@ -152,7 +154,8 @@ func New(w io.Writer, o ...gen.Opts) gen.Writer {
 		ret.opts = o[0]
 		ret.opts = o[0]
 	}
 	}
 	if ret.opts.PrettyPrint {
 	if ret.opts.PrettyPrint {
-		ret.Raw(";; github.com/kpmy/tiss/generator")
+		//ret.Raw(";; github.com/kpmy/tiss/generator")
+		ret.line = -1
 	}
 	}
 
 
 	return ret
 	return ret

+ 15 - 0
ps/impl/impl.go

@@ -0,0 +1,15 @@
+package impl
+
+import (
+	"io"
+
+	"github.com/kpmy/tiss/ir"
+	"github.com/kpmy/tiss/ps"
+	"github.com/kpmy/tiss/ps/impl/sexpr"
+)
+
+func init() {
+	ps.Parse = func(r io.Reader) (*ir.Module, error) {
+		return sexpr.Parse(r)
+	}
+}

+ 132 - 0
ps/impl/sexpr/sexpr.go

@@ -0,0 +1,132 @@
+package sexpr
+
+import (
+	"bufio"
+	"fmt"
+	"io"
+	"reflect"
+
+	"github.com/kpmy/tiss/ir"
+	"github.com/kpmy/ypk/fn"
+	. "github.com/kpmy/ypk/tc"
+	"github.com/nsf/sexp"
+)
+
+type pr struct {
+	root *sexp.Node
+	m    *ir.Module
+	e    error
+}
+
+func (p *pr) err(m ...interface{}) {
+	p.e = Error(fmt.Sprint(m...))
+	panic(p.e)
+}
+
+func node2list(n *sexp.Node) (ret []*sexp.Node) {
+	Assert(!fn.IsNil(n) && n.IsList(), 20)
+	for x := n.Children; x != nil; x = x.Next {
+		ret = append(ret, x)
+	}
+	return
+}
+
+func (p *pr) list2obj(n []*sexp.Node) (ret interface{}) {
+	var data []*sexp.Node
+	if len(n) > 1 {
+		data = n[1:]
+	}
+	switch typ := n[0].Value; {
+	case typ == "module":
+		m := &ir.Module{}
+		for _, v := range data {
+			if v.IsList() {
+				_x := p.list2obj(node2list(v))
+				switch x := _x.(type) {
+				case *ir.TypeDef:
+					m.Type = append(m.Type, x)
+				case *ir.FuncExpr:
+					m.Func = append(m.Func, x)
+				case *ir.StartExpr:
+					m.Start = x
+				default:
+					Halt(100, reflect.TypeOf(x))
+				}
+			} else {
+				p.err("unexpected scalar ", v.Value)
+			}
+		}
+		ret = m
+	case typ == "type":
+		t := &ir.TypeDef{}
+		Assert(len(data) > 0, 20)
+		var fnode *sexp.Node
+		if data[0].IsScalar() {
+			t.Name(data[0].Value)
+			fnode = data[1]
+		} else {
+			fnode = data[0]
+		}
+		f := p.list2obj(node2list(fnode))
+		t.Func = f.(*ir.FuncExpr)
+		ret = t
+	case typ == "func":
+		f := &ir.FuncExpr{}
+
+		ret = f
+	case typ == "start":
+		s := &ir.StartExpr{}
+		Assert(len(data) > 0, 20)
+		s.Var = ir.ThisVariable(data[0].Value)
+
+		ret = s
+	default:
+		Halt(100, typ)
+	}
+	Assert(ret != nil, 60)
+	return
+}
+
+func (p *pr) mod() {
+	m := p.list2obj(node2list(p.root))
+	p.m, _ = m.(*ir.Module)
+}
+
+func (p *pr) Do() (ret *ir.Module, err error) {
+	if p.root.IsList() {
+		p.root = p.root.Children
+		if p.root.IsList() {
+			if mod, _err := p.root.Nth(0); err == nil {
+				if mod.IsScalar() && mod.Value == "module" {
+					Do(func() {
+						p.mod()
+					}).Catch(nil, func(e error) {
+						p.e = e
+					}).Do()
+					err = p.e
+					ret = p.m
+				} else {
+					err = Error("not a module")
+				}
+			} else {
+				err = _err
+			}
+		} else {
+			err = Error("not a module")
+		}
+	} else {
+		err = Error("not a module")
+	}
+	return
+}
+
+func Parse(rd io.Reader) (ret *ir.Module, err error) {
+	var ctx sexp.SourceContext
+	fc := ctx.AddFile("wast", -1)
+	p := &pr{}
+	if p.root, err = sexp.Parse(bufio.NewReader(rd), fc); err == nil {
+		ret, err = p.Do()
+	}
+
+	return
+}

+ 9 - 0
ps/parser.go

@@ -0,0 +1,9 @@
+package ps
+
+import (
+	"io"
+
+	"github.com/kpmy/tiss/ir"
+)
+
+var Parse func(io.Reader) (*ir.Module, error)

+ 1 - 0
tiss.go

@@ -2,4 +2,5 @@ package tiss
 
 
 import (
 import (
 	_ "github.com/kpmy/tiss/gen/impl"
 	_ "github.com/kpmy/tiss/gen/impl"
+	_ "github.com/kpmy/tiss/ps/impl"
 )
 )

+ 46 - 0
tiss_test.go

@@ -1,6 +1,7 @@
 package tiss
 package tiss
 
 
 import (
 import (
+	"bufio"
 	"bytes"
 	"bytes"
 	"io"
 	"io"
 	"os"
 	"os"
@@ -10,6 +11,9 @@ import (
 	"github.com/kpmy/tiss/ir"
 	"github.com/kpmy/tiss/ir"
 	"github.com/kpmy/tiss/ir/ops"
 	"github.com/kpmy/tiss/ir/ops"
 	"github.com/kpmy/tiss/ir/types"
 	"github.com/kpmy/tiss/ir/types"
+	"github.com/kpmy/tiss/ps"
+	"github.com/kpmy/ypk/fn"
+	"github.com/nsf/sexp"
 )
 )
 
 
 func TestDump(t *testing.T) {
 func TestDump(t *testing.T) {
@@ -59,6 +63,45 @@ func TestDump(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestRead(t *testing.T) {
+	if f, err := os.Open("dump.wast"); err == nil {
+		defer f.Close()
+		fi, _ := f.Stat()
+		var ctx sexp.SourceContext
+		fc := ctx.AddFile("dump.wast", int(fi.Size()))
+		if nl, err := sexp.Parse(bufio.NewReader(f), fc); err == nil {
+			n := nl.Children
+			var dump func(*sexp.Node)
+			dump = func(n *sexp.Node) {
+				if n.IsList() {
+					t.Log("(")
+					for x := n.Children; x != nil; x = x.Next {
+						dump(x)
+					}
+					t.Log(")")
+				} else {
+					t.Log(n.Value)
+				}
+			}
+
+			dump(n)
+		} else {
+			t.Error(err)
+		}
+	} else {
+		t.Error(err)
+	}
+	if f, err := os.Open("dump.wast"); err == nil {
+		if m, err := ps.Parse(f); err == nil {
+			poo(t, m)
+		} else {
+			t.Error(err)
+		}
+	} else {
+		t.Error(err)
+	}
+}
+
 func TestOp(t *testing.T) {
 func TestOp(t *testing.T) {
 	t.Log(ops.Monadic(types.I32, ops.Clz))
 	t.Log(ops.Monadic(types.I32, ops.Clz))
 	t.Log(ops.Monadic(types.F32, ops.Nearest))
 	t.Log(ops.Monadic(types.F32, ops.Nearest))
@@ -156,6 +199,9 @@ func TestValidation(t *testing.T) {
 }
 }
 
 
 func poo(t *testing.T, e ir.Expression) {
 func poo(t *testing.T, e ir.Expression) {
+	if fn.IsNil(e) {
+		t.Fatal("NIL")
+	}
 	buf := bytes.NewBufferString("")
 	buf := bytes.NewBufferString("")
 	if err := gen.NewWriter(buf).WriteExpr(e); err != nil {
 	if err := gen.NewWriter(buf).WriteExpr(e); err != nil {
 		t.Error(err)
 		t.Error(err)