Răsfoiți Sursa

испрвлен баг загрузки, подошел к обработке NEW и методов

kpmy 10 ani în urmă
părinte
comite
9dfd33e7c6

BIN
code/XevDemo19.oz


+ 24 - 1
cp/constant/statement/statement.go

@@ -2,18 +2,39 @@ package statement
 
 import (
 	"strconv"
+	"ypk/assert"
 )
 
 type Statement int
 
 const (
-	ASSIGN Statement = iota
+	WRONG Statement = iota
+	ASSIGN
 	INC
 	DEC
 	INCL
 	EXCL
+	NEW
 )
 
+var this map[string]Statement
+
+func init() {
+	this = make(map[string]Statement)
+	this[ASSIGN.String()] = ASSIGN
+	this[INC.String()] = INC
+	this[DEC.String()] = DEC
+	this[INCL.String()] = INCL
+	this[EXCL.String()] = EXCL
+	this[NEW.String()] = NEW
+}
+
+func This(s string) (ret Statement) {
+	ret = this[s]
+	assert.For(ret != WRONG, 60)
+	return ret
+}
+
 func (s Statement) String() string {
 	switch s {
 	case ASSIGN:
@@ -26,6 +47,8 @@ func (s Statement) String() string {
 		return "INCL"
 	case EXCL:
 		return "EXCL"
+	case NEW:
+		return "NEW"
 	default:
 		return strconv.Itoa(int(s))
 	}

+ 27 - 1
cp/object/type.go

@@ -75,6 +75,12 @@ type BasicType interface {
 	Type() Type
 }
 
+type PointerType interface {
+	ComplexType
+	Base(...ComplexType) ComplexType
+	Name() string
+}
+
 type ArrayType interface {
 	ComplexType
 	Base() Type
@@ -140,7 +146,7 @@ func (r *rec) Name() string { return r.name }
 func (r *rec) Base() string { return r.base }
 func NewRecordType(n string, par ...string) RecordType {
 	if len(par) == 0 {
-		return &rec{name: n}
+		return &rec{}
 	} else {
 		return &rec{name: n, base: par[0]}
 	}
@@ -150,3 +156,23 @@ func (r *rec) BaseType() RecordType { return r.basetyp }
 func (r *rec) SetBase(t ComplexType) {
 	r.basetyp = t.(RecordType)
 }
+
+type ptr struct {
+	comp
+	basetyp ComplexType
+	name    string
+}
+
+func NewPointerType(n string) PointerType {
+	return &ptr{name: n}
+}
+
+func (p *ptr) Name() string { return p.name }
+func (p *ptr) Base(x ...ComplexType) ComplexType {
+	if len(x) == 1 {
+		p.basetyp = x[0]
+	} else if len(x) > 1 {
+		panic("there can be only one")
+	}
+	return p.basetyp
+}

+ 4 - 1
domain.go

@@ -27,8 +27,11 @@ func (d *stdDomain) Discover(name string) (ret context.ContextAware) {
 	if d.list != nil {
 		ret = d.list[name]
 	}
-	if name == context.UNIVERSE {
+	switch name {
+	case context.UNIVERSE:
 		ret = d.global
+	case context.HEAP:
+		ret = d.global.Discover(name)
 	}
 	return ret
 }

+ 1 - 0
fw.go

@@ -31,6 +31,7 @@ func main() {
 	global := new(stdDomain)
 	modList := module.New()
 	global.ConnectTo(context.MOD, modList)
+	global.ConnectTo(context.HEAP, scope.New())
 	t0 := time.Now()
 	ret, err := modList.Load(name)
 	t1 := time.Now()

+ 1 - 0
rt2/context/ctx.go

@@ -5,6 +5,7 @@ const (
 	SCOPE    = "fw/rt2/scope"
 	MOD      = "fw/rt2/module"
 	UNIVERSE = "fw/rt2/ctx"
+	HEAP     = "fw/rt2/scope,heap"
 )
 
 type Domain interface {

+ 9 - 0
rt2/rules/assign.go

@@ -161,6 +161,15 @@ func assignSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		default:
 			panic(fmt.Sprintln("wrong left", reflect.TypeOf(a.Left())))
 		}
+	case statement.NEW:
+		if a.Right() != nil {
+			seq, ret = expectExpr(f, a.Right(), func(f frame.Frame) (frame.Sequence, frame.WAIT) {
+				fmt.Println(rt2.DataOf(f)[a.Right()])
+				return frame.End()
+			})
+		} else {
+			return frame.End()
+		}
 	default:
 		panic(fmt.Sprintln("wrong statement", a.(node.AssignNode).Statement()))
 	}

+ 2 - 0
rt2/rules/expect.go

@@ -7,10 +7,12 @@ import (
 	"fw/rt2/frame"
 	"fw/rt2/scope"
 	"reflect"
+	"ypk/assert"
 )
 
 //функция вернет в данные родительского фрейма вычисленное значение expr
 func expectExpr(parent frame.Frame, expr node.Node, next frame.Sequence) (frame.Sequence, frame.WAIT) {
+	assert.For(expr != nil, 20)
 	sm := rt2.ScopeOf(parent)
 	switch e := expr.(type) {
 	case node.ConstantNode:

+ 4 - 1
rt2/scope/std/scope.go

@@ -182,6 +182,8 @@ func obj(o object.Object) (key scope.ID, val interface{}) {
 			val = &arr{link: o}
 		case object.RecordType:
 			val = &rec{link: o}
+		case object.PointerType:
+			val = &basic{link: o}
 		default:
 			fmt.Println("unexpected", reflect.TypeOf(t))
 		}
@@ -265,8 +267,9 @@ func (m *manager) Initialize(n node.Node, o object.Object, _val node.Node) {
 			case object.ParameterObject:
 				h.get(scope.ID{Name: next.Name()}).(*ref).ref = design(ov)
 			}
+
 		default:
-			panic("unknown value")
+			panic(fmt.Sprintln("unknown value", reflect.TypeOf(val)))
 		}
 		val = val.Link()
 	}

+ 74 - 72
xev/converter.go

@@ -79,7 +79,7 @@ func initType(typ string, conv typed) {
 	case "":
 		conv.SetType(object.NOTYPE)
 	default:
-		panic(fmt.Sprintln("no such constant type", typ))
+		panic(fmt.Sprintln("no such type", typ))
 	}
 }
 
@@ -152,74 +152,88 @@ func convertData(typ string, val string, conv convertable) {
 
 var nodeMap map[string]node.Node
 var objectMap map[string]object.Object
+var typeMap map[string]object.ComplexType
 
 func (r *Result) doType(n *Node) (ret object.ComplexType) {
-	switch n.Data.Typ.Form {
-	case "BASIC":
-		switch n.Data.Typ.Typ {
-		case "PROCEDURE":
-			t := object.NewBasicType(object.PROCEDURE)
+	ret = typeMap[n.Id]
+	if ret == nil {
+		switch n.Data.Typ.Form {
+		case "BASIC":
+			switch n.Data.Typ.Typ {
+			case "PROCEDURE":
+				t := object.NewBasicType(object.PROCEDURE)
+				link := r.findLink(n, "link")
+				if link != nil {
+					t.SetLink(r.doObject(link))
+					assert.For(t.Link() != nil, 40)
+				}
+				ret = t
+			case "CHAR", "SHORTCHAR", "INTEGER", "LONGINT", "BYTE",
+				"SHORTINT", "BOOLEAN", "REAL", "SHORTREAL", "SET":
+			case "POINTER":
+				t := object.NewPointerType(n.Data.Typ.Name)
+				base := r.findLink(n, "base")
+				if base != nil {
+					t.Base(r.doType(base))
+					assert.For(t.Base() != nil, 41)
+				}
+				ret = t
+			default:
+				fmt.Println("unknown basic type", n.Data.Typ.Typ)
+			}
+		case "DYNAMIC":
+			switch n.Data.Typ.Base {
+			case "CHAR":
+				n := object.NewDynArrayType(object.CHAR)
+				ret = n
+			case "BYTE":
+				n := object.NewDynArrayType(object.BYTE)
+				ret = n
+			case "SHORTCHAR":
+				n := object.NewDynArrayType(object.SHORTCHAR)
+				ret = n
+			default:
+				panic(fmt.Sprintln("unknown dyn type", n.Data.Typ.Typ))
+			}
+		case "ARRAY":
+			switch n.Data.Typ.Base {
+			case "CHAR":
+				n := object.NewArrayType(object.CHAR, int64(n.Data.Typ.Par))
+				ret = n
+			default:
+				panic(fmt.Sprintln("unknown array type", n.Data.Typ.Typ))
+			}
+		case "RECORD":
+			switch n.Data.Typ.Base {
+			case "NOTYP":
+				n := object.NewRecordType(n.Data.Typ.Name)
+				ret = n
+			default:
+				n := object.NewRecordType(n.Data.Typ.Name, n.Data.Typ.Base)
+				ret = n
+			}
 			link := r.findLink(n, "link")
 			if link != nil {
-				t.SetLink(r.doObject(link))
-				assert.For(t.Link() != nil, 40)
+				ret.SetLink(r.doObject(link))
+				assert.For(ret.Link() != nil, 40)
+			}
+			base := r.findLink(n, "base")
+			if base != nil {
+				ret.(object.RecordType).SetBase(r.doType(base))
+				assert.For(ret.(object.RecordType).BaseType() != nil, 41)
 			}
-			ret = t
-		case "CHAR", "SHORTCHAR", "INTEGER", "LONGINT", "BYTE",
-			"SHORTINT", "BOOLEAN", "REAL", "SHORTREAL", "SET":
-		default:
-			fmt.Println("unknown basic type", n.Data.Typ.Typ)
-		}
-	case "DYNAMIC":
-		switch n.Data.Typ.Base {
-		case "CHAR":
-			n := object.NewDynArrayType(object.CHAR)
-			ret = n
-		case "BYTE":
-			n := object.NewDynArrayType(object.BYTE)
-			ret = n
-		case "SHORTCHAR":
-			n := object.NewDynArrayType(object.SHORTCHAR)
-			ret = n
-		default:
-			panic(fmt.Sprintln("unknown dyn type", n.Data.Typ.Typ))
-		}
-	case "ARRAY":
-		switch n.Data.Typ.Base {
-		case "CHAR":
-			n := object.NewArrayType(object.CHAR, int64(n.Data.Typ.Par))
-			ret = n
-		default:
-			panic(fmt.Sprintln("unknown array type", n.Data.Typ.Typ))
-		}
-	case "RECORD":
-		switch n.Data.Typ.Base {
-		case "NOTYP":
-			n := object.NewRecordType(n.Data.Typ.Name)
-			ret = n
 		default:
-			n := object.NewRecordType(n.Data.Typ.Name, n.Data.Typ.Base)
-			ret = n
-		}
-		link := r.findLink(n, "link")
-		if link != nil {
-			ret.SetLink(r.doObject(link))
-			assert.For(ret.Link() != nil, 40)
+			panic(fmt.Sprintln("unknown form", n.Data.Typ.Form))
 		}
-		base := r.findLink(n, "base")
-		if base != nil {
-			ret.(object.RecordType).SetBase(r.doType(base))
-			assert.For(ret.(object.RecordType).BaseType() != nil, 41)
-		}
-	default:
-		panic(fmt.Sprintln("unknown form", n.Data.Typ.Form))
+	}
+	if ret != nil {
+		typeMap[n.Id] = ret
 	}
 	return ret
 }
 
-func (r *Result) doObject(n *Node) object.Object {
+func (r *Result) doObject(n *Node) (ret object.Object) {
 	assert.For(n != nil, 20)
-	var ret object.Object
 	ret = objectMap[n.Id]
 	if ret == nil {
 		switch n.Data.Obj.Mode {
@@ -254,7 +268,7 @@ func (r *Result) doObject(n *Node) object.Object {
 			panic("no such object mode")
 		}
 	}
-	if ret != nil {
+	if ret != nil && objectMap[n.Id] == nil {
 		objectMap[n.Id] = ret
 		ret.SetName(n.Data.Obj.Name)
 
@@ -342,20 +356,7 @@ func (r *Result) buildNode(n *Node) (ret node.Node) {
 			}
 		case "assign":
 			ret = node.New(constant.ASSIGN)
-			switch n.Data.Nod.Statement {
-			case ":=":
-				ret.(node.AssignNode).SetStatement(statement.ASSIGN)
-			case "INC":
-				ret.(node.AssignNode).SetStatement(statement.INC)
-			case "DEC":
-				ret.(node.AssignNode).SetStatement(statement.DEC)
-			case "INCL":
-				ret.(node.AssignNode).SetStatement(statement.INCL)
-			case "EXCL":
-				ret.(node.AssignNode).SetStatement(statement.EXCL)
-			default:
-				panic(fmt.Sprintln("unknown assign statement", n.Data.Nod.Statement))
-			}
+			ret.(node.AssignNode).SetStatement(statement.This(n.Data.Nod.Statement))
 		case "call":
 			ret = node.New(constant.CALL)
 		case "procedure":
@@ -504,6 +505,7 @@ func buildMod(r *Result) (nodeList []node.Node, scopeList map[node.Node][]object
 func DoAST(r *Result) (mod *module.Module) {
 	nodeMap = make(map[string]node.Node)
 	objectMap = make(map[string]object.Object)
+	typeMap = make(map[string]object.ComplexType)
 	mod = new(module.Module)
 	mod.Nodes, mod.Objects, mod.Types, mod.Enter = buildMod(r)
 	fmt.Println(len(mod.Nodes), len(mod.Objects))