浏览代码

добил память и все управляющие инструкции, теперь надо тестить

kpmy 9 年之前
父节点
当前提交
00d238f91d
共有 6 个文件被更改,包括 465 次插入13 次删除
  1. 二进制
      TODO.odc
  2. 11 0
      gen/impl/sexpr/sexpr.go
  3. 122 13
      ir/ast.go
  4. 262 0
      ir/flow.go
  5. 49 0
      ir/mem.go
  6. 21 0
      tiss_test.go

二进制
TODO.odc


+ 11 - 0
gen/impl/sexpr/sexpr.go

@@ -62,6 +62,10 @@ func validateAtomString(s string) {
 	}
 }
 
+func validateString(r []rune) {
+
+}
+
 func (w *wr) Atom(_v interface{}) {
 	switch v := _v.(type) {
 	case string:
@@ -74,6 +78,13 @@ func (w *wr) Atom(_v interface{}) {
 		w.Raw(strconv.Itoa(v))
 	case uint:
 		w.Raw(strconv.FormatUint(uint64(v), 10))
+	case []rune:
+		validateString(v)
+		w.Raw(`"` + string(v) + `"`)
+	case float64:
+		w.Raw(strconv.FormatFloat(v, 'g', 14, 64))
+	case float32:
+		w.Raw(strconv.FormatFloat(float64(v), 'g', 14, 32))
 	default:
 		Halt(100, "wrong atom ", reflect.TypeOf(v))
 	}

+ 122 - 13
ir/ast.go

@@ -22,13 +22,24 @@ type Node interface {
 
 type ns struct{}
 
+type snamed struct {
+	name string
+}
+
+func (n *snamed) Name(s ...string) string {
+	if len(s) > 0 {
+		Assert(s[0][0] == '$' || s[0] == "", 20)
+		n.name = s[0]
+	}
+	return n.name
+}
+
 type named struct {
 	name string
 }
 
 func (n *named) Name(s ...string) string {
 	if len(s) > 0 {
-		Assert(s[0][0] == '$' || s[0] == "", 20)
 		n.name = s[0]
 	}
 	return n.name
@@ -83,7 +94,7 @@ func (s *StartExpr) Children() (ret []interface{}) {
 
 type FuncExpr struct {
 	ns `sexpr:"func"`
-	named
+	snamed
 	Type   *TypeRef
 	Params []*Param
 	Locals []*Local
@@ -95,6 +106,32 @@ func (f *FuncExpr) Validate() (err error) {
 	return
 }
 
+type megaParam struct {
+	ns    `sexpr:"param"`
+	Types []types.Type
+}
+
+func (*megaParam) Validate() error { return nil }
+func (m *megaParam) Children() (ret []interface{}) {
+	for _, t := range m.Types {
+		ret = append(ret, t)
+	}
+	return
+}
+
+type megaLocal struct {
+	ns    `sexpr:"local"`
+	Types []types.Type
+}
+
+func (*megaLocal) Validate() error { return nil }
+func (m *megaLocal) Children() (ret []interface{}) {
+	for _, t := range m.Types {
+		ret = append(ret, t)
+	}
+	return
+}
+
 func (f *FuncExpr) Children() (ret []interface{}) {
 	if f.name != "" {
 		ret = append(ret, f.name)
@@ -104,18 +141,49 @@ func (f *FuncExpr) Children() (ret []interface{}) {
 		ret = append(ret, f.Type)
 	}
 
-	for _, p := range f.Params {
-		ret = append(ret, p)
+	{
+		var tmp []*Param
+		merge := true
+		mp := &megaParam{}
+		for _, p := range f.Params {
+			tmp = append(tmp, p)
+			mp.Types = append(mp.Types, p.typ)
+			if p.name != "" {
+				merge = false
+			}
+		}
+		if merge {
+			ret = append(ret, mp)
+		} else {
+			for _, p := range tmp {
+				ret = append(ret, p)
+			}
+		}
 	}
 
 	if !fn.IsNil(f.Result) {
 		ret = append(ret, f.Result)
 	}
-
-	for _, l := range f.Locals {
-		ret = append(ret, l)
+	{
+		var tmp []*Local
+		merge := true
+		ml := &megaLocal{}
+
+		for _, l := range f.Locals {
+			tmp = append(tmp, l)
+			ml.Types = append(ml.Types, l.typ)
+			if l.name != "" {
+				merge = false
+			}
+		}
+		if merge {
+			ret = append(ret, ml)
+		} else {
+			for _, l := range tmp {
+				ret = append(ret, l)
+			}
+		}
 	}
-
 	for _, c := range f.Code {
 		ret = append(ret, c)
 	}
@@ -156,7 +224,7 @@ func (r *ResultExpr) Children() (ret []interface{}) {
 
 type TypeDef struct {
 	ns `sexpr:"type"`
-	named
+	snamed
 	Func *FuncExpr
 }
 
@@ -190,7 +258,7 @@ type Local struct {
 }
 
 type object struct {
-	named
+	snamed
 	typ types.Type
 }
 
@@ -224,9 +292,15 @@ type Module struct {
 	Type  []*TypeDef
 	Table *TableDef
 	Imp   []*Import
+	Exp   []*Export
+	Mem   *Memory
 }
 
 func (m *Module) Children() (ret []interface{}) {
+	if m.Mem != nil {
+		ret = append(ret, m.Mem)
+	}
+
 	for _, t := range m.Type {
 		ret = append(ret, t)
 	}
@@ -235,10 +309,18 @@ func (m *Module) Children() (ret []interface{}) {
 		ret = append(ret, m.Table)
 	}
 
+	for _, i := range m.Imp {
+		ret = append(ret, i)
+	}
+
 	for _, f := range m.Func {
 		ret = append(ret, f)
 	}
 
+	for _, e := range m.Exp {
+		ret = append(ret, e)
+	}
+
 	ret = append(ret, m.Start)
 	return
 }
@@ -262,7 +344,8 @@ func (t *TableDef) Children() (ret []interface{}) {
 }
 
 type Import struct {
-	named
+	ns `sexpr:"import"`
+	snamed
 	Mod    string
 	Func   string
 	Params []*Param
@@ -276,8 +359,8 @@ func (i *Import) Children() (ret []interface{}) {
 		ret = append(ret, i.name)
 	}
 
-	ret = append(ret, `"`+i.Mod+`"`)
-	ret = append(ret, `"`+i.Func+`"`)
+	ret = append(ret, []rune(i.Mod))
+	ret = append(ret, []rune(i.Func))
 
 	for _, p := range i.Params {
 		ret = append(ret, p)
@@ -289,3 +372,29 @@ func (i *Import) Children() (ret []interface{}) {
 
 	return
 }
+
+type Export struct {
+	ns `sexpr:"export"`
+	named
+	Var Variable
+	Mem bool
+}
+
+func (e *Export) Validate() error {
+	if e.Mem != e.Var.IsEmpty() {
+		return Error("empty export")
+	}
+	return nil
+}
+
+func (e *Export) Children() (ret []interface{}) {
+
+	ret = append(ret, e.name)
+
+	if !e.Var.IsEmpty() {
+		ret = append(ret, e.Var)
+	} else {
+		ret = append(ret, "memory")
+	}
+	return
+}

+ 262 - 0
ir/flow.go

@@ -0,0 +1,262 @@
+package ir
+
+import (
+	. "github.com/kpmy/ypk/tc"
+)
+
+type Block struct {
+	ns   `sexpr:"block"`
+	End  snamed //label in the end
+	Expr []CodeExpr
+}
+
+func (b *Block) Validate() error { return nil }
+func (b *Block) Eval()           {}
+func (b *Block) Children() (ret []interface{}) {
+	if b.End.name != "" {
+		ret = append(ret, b.End.name)
+	}
+	for _, e := range b.Expr {
+		ret = append(ret, e)
+	}
+	return
+}
+
+type Loop struct {
+	ns    `sexpr:"loop"`
+	Start snamed
+	End   snamed
+	Expr  []CodeExpr
+}
+
+func (l *Loop) Validate() error { return nil }
+func (l *Loop) Eval()           {}
+func (l *Loop) Children() (ret []interface{}) {
+	if l.End.name != "" {
+		ret = append(ret, l.End.name)
+	}
+
+	if l.Start.name != "" {
+		ret = append(ret, l.Start.name)
+	}
+
+	for _, e := range l.Expr {
+		ret = append(ret, e)
+	}
+	return
+}
+
+type SelectExpr struct {
+	ns             `sexpr:"select"`
+	Expr, ElseExpr CodeExpr
+	CondExpr       CodeExpr
+}
+
+func (s *SelectExpr) Validate() error {
+	if s.Expr == nil {
+		return Error("select expr is nil")
+	}
+
+	if s.ElseExpr == nil {
+		return Error("select else expr is nil")
+	}
+
+	if s.CondExpr == nil {
+		return Error("select cond expr is nil")
+	}
+	return nil
+}
+
+func (*SelectExpr) Eval() {}
+
+func (s *SelectExpr) Children() (ret []interface{}) {
+	return append(ret, s.Expr, s.ElseExpr, s.CondExpr)
+}
+
+type If struct {
+	ns             `sexpr:"if"`
+	Expr, ElseExpr []CodeExpr
+	Name, ElseName snamed
+	CondExpr       CodeExpr
+}
+
+type thenExpr struct {
+	ns `sexpr:"then"`
+	snamed
+	Expr []CodeExpr
+}
+
+type elseExpr struct {
+	ns `sexpr:"else"`
+	snamed
+	Expr []CodeExpr
+}
+
+func (t *thenExpr) Validate() error { return nil }
+func (t *thenExpr) Children() (ret []interface{}) {
+	if t.name != "" {
+		ret = append(ret, t.name)
+	}
+	for _, e := range t.Expr {
+		ret = append(ret, e)
+	}
+	return
+}
+
+func (e *elseExpr) Validate() error { return nil }
+func (e *elseExpr) Children() (ret []interface{}) {
+	if e.name != "" {
+		ret = append(ret, e.name)
+	}
+	for _, e := range e.Expr {
+		ret = append(ret, e)
+	}
+	return
+}
+
+func (i *If) Validate() error {
+	if i.Expr == nil {
+		return Error("if expr is nil")
+	}
+
+	if i.ElseExpr == nil {
+		return Error("if else expr is nil")
+	}
+
+	if i.CondExpr == nil {
+		return Error("if cond expr is nil")
+	}
+
+	return nil
+}
+
+func (*If) Eval() {}
+
+func (s *If) Children() (ret []interface{}) {
+	ret = append(ret, s.CondExpr)
+
+	then := &thenExpr{}
+	then.snamed = s.Name
+	then.Expr = s.Expr
+
+	ret = append(ret, then)
+
+	els := &elseExpr{}
+	els.snamed = s.ElseName
+	els.Expr = s.ElseExpr
+
+	ret = append(ret, els)
+	return
+}
+
+type IfExpr struct {
+	ns             `sexpr:"if"`
+	Expr, ElseExpr CodeExpr
+	CondExpr       CodeExpr
+}
+
+func (i *IfExpr) Validate() error {
+	if i.Expr == nil {
+		return Error("if expr is nil")
+	}
+
+	if i.CondExpr == nil {
+		return Error("if cond expr is nil")
+	}
+	return nil
+}
+
+func (*IfExpr) Eval() {}
+
+func (i *IfExpr) Children() (ret []interface{}) {
+	ret = append(ret, i.CondExpr, i.Expr)
+	if i.ElseExpr != nil {
+		ret = append(ret, i.ElseExpr)
+	}
+	return
+}
+
+type Br struct {
+	ns   `sexpr:"br"`
+	Var  Variable
+	Expr CodeExpr
+}
+
+func (b *Br) Validate() error {
+	if b.Var.IsEmpty() {
+		return Error("br variable empty")
+	}
+	return nil
+}
+
+func (b *Br) Eval() {}
+
+func (b *Br) Children() (ret []interface{}) {
+	ret = append(ret, b.Var)
+
+	if b.Expr != nil {
+		ret = append(ret, b.Expr)
+	}
+
+	return
+}
+
+type BrIf struct {
+	ns         `sexpr:"br_if"`
+	Var        Variable
+	Cond, Expr CodeExpr
+}
+
+func (b *BrIf) Validate() error {
+	if b.Var.IsEmpty() {
+		return Error("br_if variable empty")
+	}
+	return nil
+}
+
+func (b *BrIf) Eval() {}
+
+func (b *BrIf) Children() (ret []interface{}) {
+	ret = append(ret, b.Var)
+
+	if b.Cond != nil {
+		ret = append(ret, b.Cond)
+	}
+	if b.Expr != nil {
+		ret = append(ret, b.Expr)
+	}
+
+	return
+}
+
+type BrTable struct {
+	ns         `sexpr:"br_table"`
+	Vars       []Variable
+	Default    Variable
+	Cond, Expr CodeExpr
+}
+
+func (b *BrTable) Validate() error {
+	if b.Default.IsEmpty() {
+		return Error("br_table variable empty")
+	}
+	if b.Cond == nil {
+		return Error("br_table condition is empty")
+	}
+	return nil
+}
+
+func (b *BrTable) Eval() {}
+
+func (b *BrTable) Children() (ret []interface{}) {
+	for _, v := range b.Vars {
+		ret = append(ret, v)
+	}
+
+	ret = append(ret, b.Default, b.Cond)
+
+	if b.Expr != nil {
+		ret = append(ret, b.Expr)
+	}
+	return
+}

+ 49 - 0
ir/mem.go

@@ -132,3 +132,52 @@ func (s *StoreExpr) Children() (ret []interface{}) {
 }
 
 func (l *StoreExpr) Eval() {}
+
+const PageSize = 65535
+
+type Memory struct {
+	ns       `sexpr:"memory"`
+	Initial  uint
+	Max      uint
+	Segments []*Segment
+}
+
+type Segment struct {
+	ns     `sexpr:"segment"`
+	Offset uint
+	Data   string
+}
+
+func (s *Segment) Validate() error { return nil }
+func (s *Segment) Children() (ret []interface{}) {
+	return append(ret, s.Offset, []rune(s.Data))
+}
+
+func (m *Memory) Validate() error {
+	if m.Initial > m.Max {
+		return Error("error page limit")
+	}
+
+	off := -1
+	for i, o := range m.Segments {
+		if off > int(o.Offset) {
+			return Error(fmt.Sprint("segments overlap", i-1, o.Offset))
+		}
+		off += int(o.Offset) + len([]rune(o.Data))
+	}
+
+	if off >= int(m.Max)*PageSize {
+		return Error("not enough memory")
+	}
+	return nil
+}
+
+func (m *Memory) Children() (ret []interface{}) {
+	ret = append(ret, m.Initial, m.Max)
+
+	for _, s := range m.Segments {
+		ret = append(ret, s)
+	}
+
+	return
+}

+ 21 - 0
tiss_test.go

@@ -100,4 +100,25 @@ func TestExpr(t *testing.T) {
 		}
 		t.Log(buf.String())
 	}
+	{
+		buf := bytes.NewBufferString("")
+		imp := &ir.Import{}
+		imp.Name("$imp")
+		imp.Mod = "mod"
+		imp.Func = "func"
+		if err := gen.NewWriter(buf).WriteExpr(imp); err != nil {
+			t.Error(err)
+		}
+		t.Log(buf.String())
+	}
+	{
+		buf := bytes.NewBufferString("")
+		c := &ir.ConstExpr{}
+		c.Type = types.F64
+		c.Value = 0.05
+		if err := gen.NewWriter(buf).WriteExpr(c); err != nil {
+			t.Error(err)
+		}
+		t.Log(buf.String())
+	}
 }