From 2a790170ec6ce8402bcf1db900c64b9b9f85493c Mon Sep 17 00:00:00 2001 From: Emil Valeev Date: Mon, 29 Apr 2024 18:43:36 +0500 Subject: [PATCH 01/11] feat(std, examples): add stream strcut and update examples --- examples/iterate_over_list/main.neva | 2 +- pkg/version.go | 2 +- std/builtin/collections.neva | 4 ++-- std/builtin/core.neva | 6 +++--- std/builtin/math.neva | 6 +++--- std/builtin/sequences.neva | 4 ++-- std/builtin/types.neva | 32 +++++++++++++++++----------- 7 files changed, 31 insertions(+), 25 deletions(-) diff --git a/examples/iterate_over_list/main.neva b/examples/iterate_over_list/main.neva index c0ca4534..898034cd 100644 --- a/examples/iterate_over_list/main.neva +++ b/examples/iterate_over_list/main.neva @@ -1,7 +1,7 @@ const lst list = [50, 30, 20, 100] component Main(start) (stop) { - nodes { Println>, Iter, Unwrap } + nodes { Println>, Iter, Unwrap } net { :start -> ($lst -> iter -> println -> unwrap) unwrap:none -> :stop diff --git a/pkg/version.go b/pkg/version.go index b1dd4f8d..8cb1f2b0 100644 --- a/pkg/version.go +++ b/pkg/version.go @@ -2,4 +2,4 @@ package pkg // Version is the current version of the language and stdlib. // Don't forget to update it before release new tag. -var Version = "0.19.1" //nolint:gochecknoglobals +var Version = "0.20.0" //nolint:gochecknoglobals diff --git a/std/builtin/collections.neva b/std/builtin/collections.neva index 5b2e2674..dc3f67fb 100644 --- a/std/builtin/collections.neva +++ b/std/builtin/collections.neva @@ -10,7 +10,7 @@ component { // If the index is out of bounds, it returns an error. // The index is zero-based. #extern(index) - pub Index(data list, idx int) (res T, err error) + pub Index(data list, idx int) (res T, err error) // Push appends new element to a list. // It allocates a copy so old list is not modified. @@ -33,5 +33,5 @@ component { pub Slice>(data T, from int, to int) (res T, err error) #extern(list_iter) - pub Iter (data list) (seq maybe) + pub Iter (data list) (seq stream) } diff --git a/std/builtin/core.neva b/std/builtin/core.neva index a79d0f61..bf1da65b 100644 --- a/std/builtin/core.neva +++ b/std/builtin/core.neva @@ -16,11 +16,11 @@ component { pub Field(msg struct {}) (msg T) #extern(match) - pub Match(data T, [case] T) ([case] T, else T) + pub Match(data T, [case] T) ([case] T, else T) #extern(unwrap) - pub Unwrap(data maybe) (some T, none struct{}) + pub Unwrap(data maybe) (some T, none struct{}) #extern(range) - pub Range(from int, to int) (data maybe) + pub Range(from int, to int) (data stream) } \ No newline at end of file diff --git a/std/builtin/math.neva b/std/builtin/math.neva index 833653d2..bbd821dd 100644 --- a/std/builtin/math.neva +++ b/std/builtin/math.neva @@ -1,12 +1,12 @@ component { #extern(int int_add, float float_add, string string_add) - pub Add(seq maybe) (res T) + pub Add(seq stream) (res T) #extern(int int_sub, float float_sub) - pub Sub(seq maybe) (res T) + pub Sub(seq stream) (res T) #extern(int int_mul, float float_mul) - pub Mul(seq maybe) (res T) + pub Mul(seq stream) (res T) #extern(int int_decr, float float_decr) pub Decr(n T) (n T) diff --git a/std/builtin/sequences.neva b/std/builtin/sequences.neva index 4b9570b1..6ec1fcd3 100644 --- a/std/builtin/sequences.neva +++ b/std/builtin/sequences.neva @@ -1,11 +1,11 @@ // PortSequencer iterates over all array-inport's slots in order // and produces stream of messages. #extern(port_sequencer) -pub component PortSequencer([port] T) (seq maybe) +pub component PortSequencer([port] T) (seq stream) // ISeqReducer reduce stream of messages to one single message. // It's expected to send result message after every processed stream. -pub interface ISeqReducer(seq maybe) (res T) +pub interface ISeqReducer(seq stream) (res T) // Reduce reduces messages from multiple connections to a single message. // It iterates over all array-inport's slots in order and streams every message diff --git a/std/builtin/types.neva b/std/builtin/types.neva index 8a5cf19b..9dfe50c7 100644 --- a/std/builtin/types.neva +++ b/std/builtin/types.neva @@ -1,15 +1,21 @@ type { - pub any // any is a top-type - pub bool // 1 byte for true | false - pub int // 64 bit integer - pub float // 64 bit floating point - pub string // utf-8 string - pub map // map from string to T - pub list // dynamic-array of T - pub maybe // optional value of T -} + pub any + pub bool + pub int + pub float + pub string + pub map + pub list + pub maybe + + pub error struct { + text string + child maybe + } -pub type error struct { - text string - child maybe -} \ No newline at end of file + pub stream struct { + data T + idx int + last bool + } +} From b5bd29981aeecbeaf1430bb3e235f4a1e4f3de4b Mon Sep 17 00:00:00 2001 From: Emil Valeev Date: Mon, 29 Apr 2024 18:44:03 +0500 Subject: [PATCH 02/11] fix,refactor(runtime:funcs): add errorFromString utility function and also remove unnecessary runtime message type validation --- internal/runtime/funcs/printf.go | 14 +- internal/runtime/funcs/read_all.go | 27 +- internal/runtime/funcs/utils.go | 9 + internal/runtime/funcs/write_all.go | 30 +- tmp.json | 2699 --------------------------- 5 files changed, 29 insertions(+), 2750 deletions(-) create mode 100644 internal/runtime/funcs/utils.go delete mode 100644 tmp.json diff --git a/internal/runtime/funcs/printf.go b/internal/runtime/funcs/printf.go index 63845b2d..99dbb944 100644 --- a/internal/runtime/funcs/printf.go +++ b/internal/runtime/funcs/printf.go @@ -69,30 +69,20 @@ func (printf) handle( res, err := format(tpl.Str(), args) if err != nil { - errMsg := map[string]runtime.Msg{ - "text": runtime.NewStrMsg(err.Error()), - } - select { case <-ctx.Done(): return - case errOut <- runtime.NewMapMsg(errMsg): + case errOut <- errorFromString(err.Error()): } - continue } if _, err := fmt.Print(res); err != nil { - errMsg := map[string]runtime.Msg{ - "text": runtime.NewStrMsg(err.Error()), - } - select { case <-ctx.Done(): return - case errOut <- runtime.NewMapMsg(errMsg): + case errOut <- errorFromString(err.Error()): } - continue } diff --git a/internal/runtime/funcs/read_all.go b/internal/runtime/funcs/read_all.go index a3969c07..ff291389 100644 --- a/internal/runtime/funcs/read_all.go +++ b/internal/runtime/funcs/read_all.go @@ -30,43 +30,40 @@ func (c readAll) Create(rio runtime.FuncIO, msg runtime.Msg) (func(ctx context.C for { var name runtime.Msg select { - case name = <-filename: case <-ctx.Done(): return + case name = <-filename: } - if name.Type() != runtime.StrMsgType { + + f, err := os.Open(name.Str()) + if err != nil { select { case <-ctx.Done(): return - case errPort <- runtime.NewMapMsg(map[string]runtime.Msg{ - "text": runtime.NewStrMsg("filename must be a string"), - }): + case errPort <- errorFromString(err.Error()): continue } } - f, err := os.Open(name.Str()) + + data, err := io.ReadAll(f) if err != nil { select { case <-ctx.Done(): return - case errPort <- runtime.NewMapMsg(map[string]runtime.Msg{ - "text": runtime.NewStrMsg(err.Error()), - }): + case errPort <- errorFromString(err.Error()): continue } } - data, err := io.ReadAll(f) - if err != nil { + + if err := f.Close(); err != nil { select { case <-ctx.Done(): return - case errPort <- runtime.NewMapMsg(map[string]runtime.Msg{ - "text": runtime.NewStrMsg(err.Error()), - }): + case errPort <- errorFromString(err.Error()): continue } } - f.Close() + select { case <-ctx.Done(): return diff --git a/internal/runtime/funcs/utils.go b/internal/runtime/funcs/utils.go new file mode 100644 index 00000000..149f9fd9 --- /dev/null +++ b/internal/runtime/funcs/utils.go @@ -0,0 +1,9 @@ +package funcs + +import "github.com/nevalang/neva/internal/runtime" + +func errorFromString(s string) runtime.Msg { + return runtime.NewMapMsg(map[string]runtime.Msg{ + "text": runtime.NewStrMsg(s), + }) +} diff --git a/internal/runtime/funcs/write_all.go b/internal/runtime/funcs/write_all.go index c2c1c04e..ea7a7fba 100644 --- a/internal/runtime/funcs/write_all.go +++ b/internal/runtime/funcs/write_all.go @@ -38,41 +38,23 @@ func (c writeAll) Create(rio runtime.FuncIO, msg runtime.Msg) (func(ctx context. return case name = <-filename: } - if name.Type() != runtime.StrMsgType { - select { - case <-ctx.Done(): - return - case errPort <- runtime.NewMapMsg(map[string]runtime.Msg{ - "text": runtime.NewStrMsg("filename must be a string"), - }): - continue - } - } + select { case <-ctx.Done(): return case data = <-dataPort: } - if name.Type() != runtime.StrMsgType { - select { - case <-ctx.Done(): - return - case errPort <- runtime.NewMapMsg(map[string]runtime.Msg{ - "text": runtime.NewStrMsg("data must be a string"), - }): - continue - } - } - if err := os.WriteFile(name.Str(), []byte(data.Str()), 0755); err != nil { + + err := os.WriteFile(name.Str(), []byte(data.Str()), 0755) + if err != nil { select { case <-ctx.Done(): return - case errPort <- runtime.NewMapMsg(map[string]runtime.Msg{ - "text": runtime.NewStrMsg("filename must be a string"), - }): + case errPort <- errorFromString(err.Error()): continue } } + select { case <-ctx.Done(): return diff --git a/tmp.json b/tmp.json deleted file mode 100644 index 8db025a7..00000000 --- a/tmp.json +++ /dev/null @@ -1,2699 +0,0 @@ -{ - "main": { - "entities": { - "Main": { - "kind": "component_entity", - "const": { "meta": { "start": {}, "stop": {} } }, - "type": {}, - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": {}, - "meta": { "start": {}, "stop": {} } - }, - "component": { - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": { - "in": { - "start": { - "typeExpr": { - "inst": { - "ref": { - "name": "any", - "meta": { "start": {}, "stop": {} } - } - }, - "meta": { "text": "any", "start": {}, "stop": {} } - }, - "meta": { - "text": "start", - "start": { "line": 3, "column": 15 }, - "stop": { "line": 3, "column": 15 } - } - } - }, - "out": { - "stop": { - "typeExpr": { - "inst": { - "ref": { - "name": "any", - "meta": { "start": {}, "stop": {} } - } - }, - "meta": { "text": "any", "start": {}, "stop": {} } - }, - "meta": { - "text": "stop", - "start": { "line": 3, "column": 23 }, - "stop": { "line": 3, "column": 23 } - } - } - } - }, - "meta": { - "text": "Main(start)(stop)", - "start": { "line": 3, "column": 10 }, - "stop": { "line": 3, "column": 27 } - } - }, - "nodes": { - "match": { - "entityRef": { - "name": "Match", - "meta": { - "text": "Match", - "start": { "line": 4, "column": 12 }, - "stop": { "line": 4, "column": 12 } - } - }, - "typeArgs": [ - { - "inst": { - "ref": { - "name": "int", - "meta": { - "text": "int", - "start": { "line": 4, "column": 18 }, - "stop": { "line": 4, "column": 18 } - } - } - }, - "meta": { - "text": "int", - "start": { "line": 4, "column": 18 }, - "stop": { "line": 4, "column": 18 } - } - } - ], - "meta": { - "text": "Match\u003cint\u003e", - "start": { "line": 4, "column": 12 }, - "stop": { "line": 4, "column": 21 } - } - }, - "next": { - "entityRef": { - "name": "PrintNext2Lines", - "meta": { - "text": "PrintNext2Lines", - "start": { "line": 4, "column": 29 }, - "stop": { "line": 4, "column": 29 } - } - }, - "meta": { - "text": "nextPrintNext2Lines", - "start": { "line": 4, "column": 24 }, - "stop": { "line": 4, "column": 29 } - } - } - }, - "net": [ - { - "normal": { - "senderSide": { - "portAddr": { - "node": "in", - "port": "start", - "meta": { - "text": ":start", - "start": { "line": 6, "column": 8 }, - "stop": { "line": 6, "column": 9 } - } - }, - "meta": { - "text": ":start", - "start": { "line": 6, "column": 8 }, - "stop": { "line": 6, "column": 9 } - } - }, - "receiverSide": { - "deferredConnections": [ - { - "normal": { - "senderSide": { - "literal": { - "value": { - "typeExpr": { - "inst": { - "ref": { - "name": "int", - "meta": { "start": {}, "stop": {} } - } - } - }, - "int": 99, - "meta": { - "text": "99", - "start": { "line": 6, "column": 19 }, - "stop": { "line": 6, "column": 19 } - } - }, - "meta": { "start": {}, "stop": {} } - }, - "meta": { - "text": "99", - "start": { "line": 6, "column": 19 }, - "stop": { "line": 6, "column": 19 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "next", - "port": "n", - "meta": { - "text": "next:n", - "start": { "line": 6, "column": 25 }, - "stop": { "line": 6, "column": 30 } - } - }, - "meta": { "start": {}, "stop": {} } - } - ] - } - }, - "meta": { - "text": "next:n-\u003ematch:data", - "start": { "line": 6, "column": 25 }, - "stop": { "line": 6, "column": 41 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "next", - "port": "n", - "meta": { - "text": "next:n", - "start": { "line": 6, "column": 25 }, - "stop": { "line": 6, "column": 30 } - } - }, - "meta": { - "text": "next:n", - "start": { "line": 6, "column": 25 }, - "stop": { "line": 6, "column": 30 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "match", - "port": "data", - "meta": { - "text": "match:data", - "start": { "line": 6, "column": 35 }, - "stop": { "line": 6, "column": 41 } - } - }, - "meta": { - "text": "match:data", - "start": { "line": 6, "column": 35 }, - "stop": { "line": 6, "column": 41 } - } - } - ] - } - }, - "meta": { - "text": "next:n-\u003ematch:data", - "start": { "line": 6, "column": 25 }, - "stop": { "line": 6, "column": 41 } - } - } - ] - } - }, - "meta": { - "text": ":start-\u003e(99-\u003enext:n-\u003ematch:data)", - "start": { "line": 6, "column": 8 }, - "stop": { "line": 6, "column": 45 } - } - }, - { - "normal": { - "senderSide": { - "literal": { - "value": { - "typeExpr": { - "inst": { - "ref": { - "name": "int", - "meta": { "start": {}, "stop": {} } - } - } - }, - "int": -1, - "meta": { - "text": "-1", - "start": { "line": 7, "column": 8 }, - "stop": { "line": 7, "column": 9 } - } - }, - "meta": { "start": {}, "stop": {} } - }, - "meta": { - "text": "-1", - "start": { "line": 7, "column": 8 }, - "stop": { "line": 7, "column": 9 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "match", - "port": "case", - "idx": 0, - "meta": { - "text": "match:case[0]", - "start": { "line": 7, "column": 14 }, - "stop": { "line": 7, "column": 26 } - } - }, - "meta": { "start": {}, "stop": {} } - } - ] - } - }, - "meta": { - "text": "match:case[0]-\u003e:stop", - "start": { "line": 7, "column": 14 }, - "stop": { "line": 7, "column": 32 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "match", - "port": "case", - "idx": 0, - "meta": { - "text": "match:case[0]", - "start": { "line": 7, "column": 14 }, - "stop": { "line": 7, "column": 26 } - } - }, - "meta": { - "text": "match:case[0]", - "start": { "line": 7, "column": 14 }, - "stop": { "line": 7, "column": 26 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "out", - "port": "stop", - "meta": { - "text": ":stop", - "start": { "line": 7, "column": 31 }, - "stop": { "line": 7, "column": 32 } - } - }, - "meta": { - "text": ":stop", - "start": { "line": 7, "column": 31 }, - "stop": { "line": 7, "column": 32 } - } - } - ] - } - }, - "meta": { - "text": "match:case[0]-\u003e:stop", - "start": { "line": 7, "column": 14 }, - "stop": { "line": 7, "column": 32 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "match", - "port": "else", - "meta": { - "text": "match:else", - "start": { "line": 8, "column": 8 }, - "stop": { "line": 8, "column": 14 } - } - }, - "meta": { - "text": "match:else", - "start": { "line": 8, "column": 8 }, - "stop": { "line": 8, "column": 14 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "next", - "port": "n", - "meta": { - "text": "next:n", - "start": { "line": 8, "column": 22 }, - "stop": { "line": 8, "column": 27 } - } - }, - "meta": { - "text": "next:n", - "start": { "line": 8, "column": 22 }, - "stop": { "line": 8, "column": 27 } - } - } - ] - } - }, - "meta": { - "text": "match:else-\u003enext:n", - "start": { "line": 8, "column": 8 }, - "stop": { "line": 8, "column": 27 } - } - } - ], - "meta": { "start": {}, "stop": {} } - } - }, - "PrintFirstLine": { - "kind": "component_entity", - "const": { "meta": { "start": {}, "stop": {} } }, - "type": {}, - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": {}, - "meta": { "start": {}, "stop": {} } - }, - "component": { - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": { - "in": { - "n": { - "typeExpr": { - "inst": { - "ref": { - "name": "int", - "meta": { - "text": "int", - "start": { "line": 31, "column": 27 }, - "stop": { "line": 31, "column": 27 } - } - } - }, - "meta": { - "text": "int", - "start": { "line": 31, "column": 27 }, - "stop": { "line": 31, "column": 27 } - } - }, - "meta": { - "text": "nint", - "start": { "line": 31, "column": 25 }, - "stop": { "line": 31, "column": 27 } - } - } - }, - "out": { - "n": { - "typeExpr": { - "inst": { - "ref": { - "name": "int", - "meta": { - "text": "int", - "start": { "line": 31, "column": 35 }, - "stop": { "line": 31, "column": 35 } - } - } - }, - "meta": { - "text": "int", - "start": { "line": 31, "column": 35 }, - "stop": { "line": 31, "column": 35 } - } - }, - "meta": { - "text": "nint", - "start": { "line": 31, "column": 33 }, - "stop": { "line": 31, "column": 35 } - } - } - } - }, - "meta": { - "text": "PrintFirstLine(nint)(nint)", - "start": { "line": 31, "column": 10 }, - "stop": { "line": 31, "column": 38 } - } - }, - "nodes": { - "lock": { - "entityRef": { - "name": "Lock", - "meta": { - "text": "Lock", - "start": { "line": 32, "column": 54 }, - "stop": { "line": 32, "column": 54 } - } - }, - "typeArgs": [ - { - "inst": { - "ref": { - "name": "int", - "meta": { - "text": "int", - "start": { "line": 32, "column": 59 }, - "stop": { "line": 32, "column": 59 } - } - } - }, - "meta": { - "text": "int", - "start": { "line": 32, "column": 59 }, - "stop": { "line": 32, "column": 59 } - } - } - ], - "meta": { - "text": "Lock\u003cint\u003e", - "start": { "line": 32, "column": 54 }, - "stop": { "line": 32, "column": 62 } - } - }, - "match": { - "entityRef": { - "name": "Match", - "meta": { - "text": "Match", - "start": { "line": 32, "column": 12 }, - "stop": { "line": 32, "column": 12 } - } - }, - "typeArgs": [ - { - "inst": { - "ref": { - "name": "int", - "meta": { - "text": "int", - "start": { "line": 32, "column": 18 }, - "stop": { "line": 32, "column": 18 } - } - } - }, - "meta": { - "text": "int", - "start": { "line": 32, "column": 18 }, - "stop": { "line": 32, "column": 18 } - } - } - ], - "meta": { - "text": "Match\u003cint\u003e", - "start": { "line": 32, "column": 12 }, - "stop": { "line": 32, "column": 21 } - } - }, - "printf": { - "entityRef": { - "name": "Printf", - "meta": { - "text": "Printf", - "start": { "line": 32, "column": 41 }, - "stop": { "line": 32, "column": 41 } - } - }, - "typeArgs": [ - { - "inst": { - "ref": { - "name": "int", - "meta": { - "text": "int", - "start": { "line": 32, "column": 48 }, - "stop": { "line": 32, "column": 48 } - } - } - }, - "meta": { - "text": "int", - "start": { "line": 32, "column": 48 }, - "stop": { "line": 32, "column": 48 } - } - } - ], - "meta": { - "text": "Printf\u003cint\u003e", - "start": { "line": 32, "column": 41 }, - "stop": { "line": 32, "column": 51 } - } - }, - "println": { - "entityRef": { - "name": "Println", - "meta": { - "text": "Println", - "start": { "line": 32, "column": 24 }, - "stop": { "line": 32, "column": 24 } - } - }, - "typeArgs": [ - { - "inst": { - "ref": { - "name": "string", - "meta": { - "text": "string", - "start": { "line": 32, "column": 32 }, - "stop": { "line": 32, "column": 32 } - } - } - }, - "meta": { - "text": "string", - "start": { "line": 32, "column": 32 }, - "stop": { "line": 32, "column": 32 } - } - } - ], - "meta": { - "text": "Println\u003cstring\u003e", - "start": { "line": 32, "column": 24 }, - "stop": { "line": 32, "column": 38 } - } - } - }, - "net": [ - { - "normal": { - "senderSide": { - "portAddr": { - "node": "in", - "port": "n", - "meta": { - "text": ":n", - "start": { "line": 34, "column": 8 }, - "stop": { "line": 34, "column": 9 } - } - }, - "meta": { - "text": ":n", - "start": { "line": 34, "column": 8 }, - "stop": { "line": 34, "column": 9 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "match", - "port": "data", - "meta": { - "text": "match:data", - "start": { "line": 34, "column": 15 }, - "stop": { "line": 34, "column": 21 } - } - }, - "meta": { - "text": "match:data", - "start": { "line": 34, "column": 15 }, - "stop": { "line": 34, "column": 21 } - } - }, - { - "portAddr": { - "node": "lock", - "port": "data", - "meta": { - "text": "lock:data", - "start": { "line": 34, "column": 27 }, - "stop": { "line": 34, "column": 32 } - } - }, - "meta": { - "text": "lock:data", - "start": { "line": 34, "column": 27 }, - "stop": { "line": 34, "column": 32 } - } - } - ] - } - }, - "meta": { - "text": ":n-\u003e[match:data,lock:data]", - "start": { "line": 34, "column": 8 }, - "stop": { "line": 34, "column": 36 } - } - }, - { - "normal": { - "senderSide": { - "literal": { - "value": { - "typeExpr": { - "inst": { - "ref": { - "name": "int", - "meta": { "start": {}, "stop": {} } - } - } - }, - "int": 0, - "meta": { - "text": "0", - "start": { "line": 36, "column": 8 }, - "stop": { "line": 36, "column": 8 } - } - }, - "meta": { "start": {}, "stop": {} } - }, - "meta": { - "text": "0", - "start": { "line": 36, "column": 8 }, - "stop": { "line": 36, "column": 8 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "match", - "port": "case", - "idx": 0, - "meta": { - "text": "match:case[0]", - "start": { "line": 36, "column": 13 }, - "stop": { "line": 36, "column": 25 } - } - }, - "meta": { "start": {}, "stop": {} } - } - ] - } - }, - "meta": { - "text": "match:case[0]-\u003e($firstLine3-\u003eprintln:data)", - "start": { "line": 36, "column": 13 }, - "stop": { "line": 36, "column": 58 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "match", - "port": "case", - "idx": 0, - "meta": { - "text": "match:case[0]", - "start": { "line": 36, "column": 13 }, - "stop": { "line": 36, "column": 25 } - } - }, - "meta": { - "text": "match:case[0]", - "start": { "line": 36, "column": 13 }, - "stop": { "line": 36, "column": 25 } - } - }, - "receiverSide": { - "deferredConnections": [ - { - "normal": { - "senderSide": { - "literal": { - "ref": { - "name": "firstLine3", - "meta": { - "text": "firstLine3", - "start": { "line": 36, "column": 32 }, - "stop": { "line": 36, "column": 32 } - } - }, - "meta": { "start": {}, "stop": {} } - }, - "meta": { - "text": "$firstLine3", - "start": { "line": 36, "column": 31 }, - "stop": { "line": 36, "column": 32 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "println", - "port": "data", - "meta": { - "text": "println:data", - "start": { "line": 36, "column": 46 }, - "stop": { "line": 36, "column": 54 } - } - }, - "meta": { - "text": "println:data", - "start": { "line": 36, "column": 46 }, - "stop": { "line": 36, "column": 54 } - } - } - ] - } - }, - "meta": { - "text": "$firstLine3-\u003eprintln:data", - "start": { "line": 36, "column": 31 }, - "stop": { "line": 36, "column": 54 } - } - } - ] - } - }, - "meta": { - "text": "match:case[0]-\u003e($firstLine3-\u003eprintln:data)", - "start": { "line": 36, "column": 13 }, - "stop": { "line": 36, "column": 58 } - } - }, - { - "normal": { - "senderSide": { - "literal": { - "value": { - "typeExpr": { - "inst": { - "ref": { - "name": "int", - "meta": { "start": {}, "stop": {} } - } - } - }, - "int": 1, - "meta": { - "text": "1", - "start": { "line": 37, "column": 8 }, - "stop": { "line": 37, "column": 8 } - } - }, - "meta": { "start": {}, "stop": {} } - }, - "meta": { - "text": "1", - "start": { "line": 37, "column": 8 }, - "stop": { "line": 37, "column": 8 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "match", - "port": "case", - "idx": 1, - "meta": { - "text": "match:case[1]", - "start": { "line": 37, "column": 13 }, - "stop": { "line": 37, "column": 25 } - } - }, - "meta": { "start": {}, "stop": {} } - } - ] - } - }, - "meta": { - "text": "match:case[1]-\u003e($firstLine2-\u003eprintln:data)", - "start": { "line": 37, "column": 13 }, - "stop": { "line": 37, "column": 58 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "match", - "port": "case", - "idx": 1, - "meta": { - "text": "match:case[1]", - "start": { "line": 37, "column": 13 }, - "stop": { "line": 37, "column": 25 } - } - }, - "meta": { - "text": "match:case[1]", - "start": { "line": 37, "column": 13 }, - "stop": { "line": 37, "column": 25 } - } - }, - "receiverSide": { - "deferredConnections": [ - { - "normal": { - "senderSide": { - "literal": { - "ref": { - "name": "firstLine2", - "meta": { - "text": "firstLine2", - "start": { "line": 37, "column": 32 }, - "stop": { "line": 37, "column": 32 } - } - }, - "meta": { "start": {}, "stop": {} } - }, - "meta": { - "text": "$firstLine2", - "start": { "line": 37, "column": 31 }, - "stop": { "line": 37, "column": 32 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "println", - "port": "data", - "meta": { - "text": "println:data", - "start": { "line": 37, "column": 46 }, - "stop": { "line": 37, "column": 54 } - } - }, - "meta": { - "text": "println:data", - "start": { "line": 37, "column": 46 }, - "stop": { "line": 37, "column": 54 } - } - } - ] - } - }, - "meta": { - "text": "$firstLine2-\u003eprintln:data", - "start": { "line": 37, "column": 31 }, - "stop": { "line": 37, "column": 54 } - } - } - ] - } - }, - "meta": { - "text": "match:case[1]-\u003e($firstLine2-\u003eprintln:data)", - "start": { "line": 37, "column": 13 }, - "stop": { "line": 37, "column": 58 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "match", - "port": "else", - "meta": { - "text": "match:else", - "start": { "line": 38, "column": 8 }, - "stop": { "line": 38, "column": 14 } - } - }, - "meta": { - "text": "match:else", - "start": { "line": 38, "column": 8 }, - "stop": { "line": 38, "column": 14 } - } - }, - "receiverSide": { - "deferredConnections": [ - { - "normal": { - "senderSide": { - "literal": { - "ref": { - "name": "firstLine1", - "meta": { - "text": "firstLine1", - "start": { "line": 40, "column": 14 }, - "stop": { "line": 40, "column": 14 } - } - }, - "meta": { "start": {}, "stop": {} } - }, - "meta": { - "text": "$firstLine1", - "start": { "line": 40, "column": 13 }, - "stop": { "line": 40, "column": 14 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "printf", - "port": "tpl", - "meta": { - "text": "printf:tpl", - "start": { "line": 40, "column": 28 }, - "stop": { "line": 40, "column": 35 } - } - }, - "meta": { - "text": "printf:tpl", - "start": { "line": 40, "column": 28 }, - "stop": { "line": 40, "column": 35 } - } - } - ] - } - }, - "meta": { - "text": "$firstLine1-\u003eprintf:tpl", - "start": { "line": 40, "column": 13 }, - "stop": { "line": 40, "column": 35 } - } - } - ], - "receivers": [ - { - "portAddr": { - "node": "printf", - "port": "args", - "idx": 0, - "meta": { - "text": "printf:args[0]", - "start": { "line": 39, "column": 12 }, - "stop": { "line": 39, "column": 25 } - } - }, - "meta": { - "text": "printf:args[0]", - "start": { "line": 39, "column": 12 }, - "stop": { "line": 39, "column": 25 } - } - } - ] - } - }, - "meta": { - "text": "match:else-\u003e[\nprintf:args[0],\n($firstLine1-\u003eprintf:tpl)\n]", - "start": { "line": 38, "column": 8 }, - "stop": { "line": 41, "column": 8 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "println", - "port": "sig", - "meta": { - "text": "println:sig", - "start": { "line": 43, "column": 9 }, - "stop": { "line": 43, "column": 17 } - } - }, - "meta": { - "text": "println:sig", - "start": { "line": 43, "column": 9 }, - "stop": { "line": 43, "column": 17 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "lock", - "port": "sig", - "meta": { - "text": "lock:sig", - "start": { "line": 43, "column": 41 }, - "stop": { "line": 43, "column": 46 } - } - }, - "meta": { - "text": "lock:sig", - "start": { "line": 43, "column": 41 }, - "stop": { "line": 43, "column": 46 } - } - } - ] - } - }, - "meta": { - "text": "[println:sig,printf:args[0]]-\u003elock:sig", - "start": { "line": 43, "column": 8 }, - "stop": { "line": 43, "column": 46 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "printf", - "port": "args", - "idx": 0, - "meta": { - "text": "printf:args[0]", - "start": { "line": 43, "column": 22 }, - "stop": { "line": 43, "column": 35 } - } - }, - "meta": { - "text": "printf:args[0]", - "start": { "line": 43, "column": 22 }, - "stop": { "line": 43, "column": 35 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "lock", - "port": "sig", - "meta": { - "text": "lock:sig", - "start": { "line": 43, "column": 41 }, - "stop": { "line": 43, "column": 46 } - } - }, - "meta": { - "text": "lock:sig", - "start": { "line": 43, "column": 41 }, - "stop": { "line": 43, "column": 46 } - } - } - ] - } - }, - "meta": { - "text": "[println:sig,printf:args[0]]-\u003elock:sig", - "start": { "line": 43, "column": 8 }, - "stop": { "line": 43, "column": 46 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "lock", - "port": "data", - "meta": { - "text": "lock:data", - "start": { "line": 44, "column": 8 }, - "stop": { "line": 44, "column": 13 } - } - }, - "meta": { - "text": "lock:data", - "start": { "line": 44, "column": 8 }, - "stop": { "line": 44, "column": 13 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "out", - "port": "n", - "meta": { - "text": ":n", - "start": { "line": 44, "column": 21 }, - "stop": { "line": 44, "column": 22 } - } - }, - "meta": { - "text": ":n", - "start": { "line": 44, "column": 21 }, - "stop": { "line": 44, "column": 22 } - } - } - ] - } - }, - "meta": { - "text": "lock:data-\u003e:n", - "start": { "line": 44, "column": 8 }, - "stop": { "line": 44, "column": 22 } - } - } - ], - "meta": { "start": {}, "stop": {} } - } - }, - "PrintNext2Lines": { - "kind": "component_entity", - "const": { "meta": { "start": {}, "stop": {} } }, - "type": {}, - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": {}, - "meta": { "start": {}, "stop": {} } - }, - "component": { - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": { - "in": { - "n": { - "typeExpr": { - "inst": { - "ref": { - "name": "int", - "meta": { - "text": "int", - "start": { "line": 12, "column": 28 }, - "stop": { "line": 12, "column": 28 } - } - } - }, - "meta": { - "text": "int", - "start": { "line": 12, "column": 28 }, - "stop": { "line": 12, "column": 28 } - } - }, - "meta": { - "text": "nint", - "start": { "line": 12, "column": 26 }, - "stop": { "line": 12, "column": 28 } - } - } - }, - "out": { - "n": { - "typeExpr": { - "inst": { - "ref": { - "name": "int", - "meta": { - "text": "int", - "start": { "line": 12, "column": 36 }, - "stop": { "line": 12, "column": 36 } - } - } - }, - "meta": { - "text": "int", - "start": { "line": 12, "column": 36 }, - "stop": { "line": 12, "column": 36 } - } - }, - "meta": { - "text": "nint", - "start": { "line": 12, "column": 34 }, - "stop": { "line": 12, "column": 36 } - } - } - } - }, - "meta": { - "text": "PrintNext2Lines(nint)(nint)", - "start": { "line": 12, "column": 10 }, - "stop": { "line": 12, "column": 39 } - } - }, - "nodes": { - "decr": { - "entityRef": { - "name": "Decr", - "meta": { - "text": "Decr", - "start": { "line": 14, "column": 15 }, - "stop": { "line": 14, "column": 15 } - } - }, - "typeArgs": [ - { - "inst": { - "ref": { - "name": "int", - "meta": { - "text": "int", - "start": { "line": 14, "column": 20 }, - "stop": { "line": 14, "column": 20 } - } - } - }, - "meta": { - "text": "int", - "start": { "line": 14, "column": 20 }, - "stop": { "line": 14, "column": 20 } - } - } - ], - "meta": { - "text": "decrDecr\u003cint\u003e\n", - "start": { "line": 14, "column": 8 }, - "stop": { "line": 14, "column": 24 } - } - }, - "first": { - "entityRef": { - "name": "PrintFirstLine", - "meta": { - "text": "PrintFirstLine", - "start": { "line": 15, "column": 15 }, - "stop": { "line": 15, "column": 15 } - } - }, - "meta": { - "text": "firstPrintFirstLine\n", - "start": { "line": 15, "column": 8 }, - "stop": { "line": 15, "column": 29 } - } - }, - "second": { - "entityRef": { - "name": "PrintSecondLine", - "meta": { - "text": "PrintSecondLine", - "start": { "line": 16, "column": 15 }, - "stop": { "line": 16, "column": 15 } - } - }, - "meta": { - "text": "secondPrintSecondLine\n", - "start": { "line": 16, "column": 8 }, - "stop": { "line": 16, "column": 30 } - } - } - }, - "net": [ - { - "normal": { - "senderSide": { - "portAddr": { - "node": "in", - "port": "n", - "meta": { - "text": ":n", - "start": { "line": 19, "column": 8 }, - "stop": { "line": 19, "column": 9 } - } - }, - "meta": { - "text": ":n", - "start": { "line": 19, "column": 8 }, - "stop": { "line": 19, "column": 9 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "first", - "port": "n", - "meta": { - "text": "first:n", - "start": { "line": 19, "column": 14 }, - "stop": { "line": 19, "column": 20 } - } - }, - "meta": { "start": {}, "stop": {} } - } - ] - } - }, - "meta": { - "text": "first:n-\u003edecr:n-\u003esecond:n-\u003e:n", - "start": { "line": 19, "column": 14 }, - "stop": { "line": 19, "column": 48 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "first", - "port": "n", - "meta": { - "text": "first:n", - "start": { "line": 19, "column": 14 }, - "stop": { "line": 19, "column": 20 } - } - }, - "meta": { - "text": "first:n", - "start": { "line": 19, "column": 14 }, - "stop": { "line": 19, "column": 20 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "decr", - "port": "n", - "meta": { - "text": "decr:n", - "start": { "line": 19, "column": 25 }, - "stop": { "line": 19, "column": 30 } - } - }, - "meta": { "start": {}, "stop": {} } - } - ] - } - }, - "meta": { - "text": "decr:n-\u003esecond:n-\u003e:n", - "start": { "line": 19, "column": 25 }, - "stop": { "line": 19, "column": 48 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "decr", - "port": "n", - "meta": { - "text": "decr:n", - "start": { "line": 19, "column": 25 }, - "stop": { "line": 19, "column": 30 } - } - }, - "meta": { - "text": "decr:n", - "start": { "line": 19, "column": 25 }, - "stop": { "line": 19, "column": 30 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "second", - "port": "n", - "meta": { - "text": "second:n", - "start": { "line": 19, "column": 35 }, - "stop": { "line": 19, "column": 42 } - } - }, - "meta": { "start": {}, "stop": {} } - } - ] - } - }, - "meta": { - "text": "second:n-\u003e:n", - "start": { "line": 19, "column": 35 }, - "stop": { "line": 19, "column": 48 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "second", - "port": "n", - "meta": { - "text": "second:n", - "start": { "line": 19, "column": 35 }, - "stop": { "line": 19, "column": 42 } - } - }, - "meta": { - "text": "second:n", - "start": { "line": 19, "column": 35 }, - "stop": { "line": 19, "column": 42 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "out", - "port": "n", - "meta": { - "text": ":n", - "start": { "line": 19, "column": 47 }, - "stop": { "line": 19, "column": 48 } - } - }, - "meta": { - "text": ":n", - "start": { "line": 19, "column": 47 }, - "stop": { "line": 19, "column": 48 } - } - } - ] - } - }, - "meta": { - "text": "second:n-\u003e:n", - "start": { "line": 19, "column": 35 }, - "stop": { "line": 19, "column": 48 } - } - } - ], - "meta": { "start": {}, "stop": {} } - } - }, - "PrintSecondLine": { - "kind": "component_entity", - "const": { "meta": { "start": {}, "stop": {} } }, - "type": {}, - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": {}, - "meta": { "start": {}, "stop": {} } - }, - "component": { - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": { - "in": { - "n": { - "typeExpr": { - "inst": { - "ref": { - "name": "int", - "meta": { - "text": "int", - "start": { "line": 57, "column": 28 }, - "stop": { "line": 57, "column": 28 } - } - } - }, - "meta": { - "text": "int", - "start": { "line": 57, "column": 28 }, - "stop": { "line": 57, "column": 28 } - } - }, - "meta": { - "text": "nint", - "start": { "line": 57, "column": 26 }, - "stop": { "line": 57, "column": 28 } - } - } - }, - "out": { - "n": { - "typeExpr": { - "inst": { - "ref": { - "name": "int", - "meta": { - "text": "int", - "start": { "line": 57, "column": 36 }, - "stop": { "line": 57, "column": 36 } - } - } - }, - "meta": { - "text": "int", - "start": { "line": 57, "column": 36 }, - "stop": { "line": 57, "column": 36 } - } - }, - "meta": { - "text": "nint", - "start": { "line": 57, "column": 34 }, - "stop": { "line": 57, "column": 36 } - } - } - } - }, - "meta": { - "text": "PrintSecondLine(nint)(nint)", - "start": { "line": 57, "column": 10 }, - "stop": { "line": 57, "column": 39 } - } - }, - "nodes": { - "lock": { - "entityRef": { - "name": "Lock", - "meta": { - "text": "Lock", - "start": { "line": 58, "column": 24 }, - "stop": { "line": 58, "column": 24 } - } - }, - "typeArgs": [ - { - "inst": { - "ref": { - "name": "int", - "meta": { - "text": "int", - "start": { "line": 58, "column": 29 }, - "stop": { "line": 58, "column": 29 } - } - } - }, - "meta": { - "text": "int", - "start": { "line": 58, "column": 29 }, - "stop": { "line": 58, "column": 29 } - } - } - ], - "meta": { - "text": "Lock\u003cint\u003e", - "start": { "line": 58, "column": 24 }, - "stop": { "line": 58, "column": 32 } - } - }, - "match": { - "entityRef": { - "name": "Match", - "meta": { - "text": "Match", - "start": { "line": 58, "column": 12 }, - "stop": { "line": 58, "column": 12 } - } - }, - "typeArgs": [ - { - "inst": { - "ref": { - "name": "int", - "meta": { - "text": "int", - "start": { "line": 58, "column": 18 }, - "stop": { "line": 58, "column": 18 } - } - } - }, - "meta": { - "text": "int", - "start": { "line": 58, "column": 18 }, - "stop": { "line": 58, "column": 18 } - } - } - ], - "meta": { - "text": "Match\u003cint\u003e", - "start": { "line": 58, "column": 12 }, - "stop": { "line": 58, "column": 21 } - } - }, - "printf": { - "entityRef": { - "name": "Printf", - "meta": { - "text": "Printf", - "start": { "line": 58, "column": 35 }, - "stop": { "line": 58, "column": 35 } - } - }, - "typeArgs": [ - { - "inst": { - "ref": { - "name": "int", - "meta": { - "text": "int", - "start": { "line": 58, "column": 42 }, - "stop": { "line": 58, "column": 42 } - } - } - }, - "meta": { - "text": "int", - "start": { "line": 58, "column": 42 }, - "stop": { "line": 58, "column": 42 } - } - } - ], - "meta": { - "text": "Printf\u003cint\u003e", - "start": { "line": 58, "column": 35 }, - "stop": { "line": 58, "column": 45 } - } - }, - "println": { - "entityRef": { - "name": "Println", - "meta": { - "text": "Println", - "start": { "line": 58, "column": 48 }, - "stop": { "line": 58, "column": 48 } - } - }, - "typeArgs": [ - { - "inst": { - "ref": { - "name": "string", - "meta": { - "text": "string", - "start": { "line": 58, "column": 56 }, - "stop": { "line": 58, "column": 56 } - } - } - }, - "meta": { - "text": "string", - "start": { "line": 58, "column": 56 }, - "stop": { "line": 58, "column": 56 } - } - } - ], - "meta": { - "text": "Println\u003cstring\u003e", - "start": { "line": 58, "column": 48 }, - "stop": { "line": 58, "column": 62 } - } - } - }, - "net": [ - { - "normal": { - "senderSide": { - "portAddr": { - "node": "in", - "port": "n", - "meta": { - "text": ":n", - "start": { "line": 60, "column": 8 }, - "stop": { "line": 60, "column": 9 } - } - }, - "meta": { - "text": ":n", - "start": { "line": 60, "column": 8 }, - "stop": { "line": 60, "column": 9 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "match", - "port": "data", - "meta": { - "text": "match:data", - "start": { "line": 60, "column": 15 }, - "stop": { "line": 60, "column": 21 } - } - }, - "meta": { - "text": "match:data", - "start": { "line": 60, "column": 15 }, - "stop": { "line": 60, "column": 21 } - } - }, - { - "portAddr": { - "node": "lock", - "port": "data", - "meta": { - "text": "lock:data", - "start": { "line": 60, "column": 27 }, - "stop": { "line": 60, "column": 32 } - } - }, - "meta": { - "text": "lock:data", - "start": { "line": 60, "column": 27 }, - "stop": { "line": 60, "column": 32 } - } - } - ] - } - }, - "meta": { - "text": ":n-\u003e[match:data,lock:data]", - "start": { "line": 60, "column": 8 }, - "stop": { "line": 60, "column": 36 } - } - }, - { - "normal": { - "senderSide": { - "literal": { - "value": { - "typeExpr": { - "inst": { - "ref": { - "name": "int", - "meta": { "start": {}, "stop": {} } - } - } - }, - "int": -1, - "meta": { - "text": "-1", - "start": { "line": 62, "column": 8 }, - "stop": { "line": 62, "column": 9 } - } - }, - "meta": { "start": {}, "stop": {} } - }, - "meta": { - "text": "-1", - "start": { "line": 62, "column": 8 }, - "stop": { "line": 62, "column": 9 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "match", - "port": "case", - "idx": 0, - "meta": { - "text": "match:case[0]", - "start": { "line": 62, "column": 14 }, - "stop": { "line": 62, "column": 26 } - } - }, - "meta": { "start": {}, "stop": {} } - } - ] - } - }, - "meta": { - "text": "match:case[0]-\u003e($secondLine4-\u003eprintln:data)", - "start": { "line": 62, "column": 14 }, - "stop": { "line": 62, "column": 60 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "match", - "port": "case", - "idx": 0, - "meta": { - "text": "match:case[0]", - "start": { "line": 62, "column": 14 }, - "stop": { "line": 62, "column": 26 } - } - }, - "meta": { - "text": "match:case[0]", - "start": { "line": 62, "column": 14 }, - "stop": { "line": 62, "column": 26 } - } - }, - "receiverSide": { - "deferredConnections": [ - { - "normal": { - "senderSide": { - "literal": { - "ref": { - "name": "secondLine4", - "meta": { - "text": "secondLine4", - "start": { "line": 62, "column": 33 }, - "stop": { "line": 62, "column": 33 } - } - }, - "meta": { "start": {}, "stop": {} } - }, - "meta": { - "text": "$secondLine4", - "start": { "line": 62, "column": 32 }, - "stop": { "line": 62, "column": 33 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "println", - "port": "data", - "meta": { - "text": "println:data", - "start": { "line": 62, "column": 48 }, - "stop": { "line": 62, "column": 56 } - } - }, - "meta": { - "text": "println:data", - "start": { "line": 62, "column": 48 }, - "stop": { "line": 62, "column": 56 } - } - } - ] - } - }, - "meta": { - "text": "$secondLine4-\u003eprintln:data", - "start": { "line": 62, "column": 32 }, - "stop": { "line": 62, "column": 56 } - } - } - ] - } - }, - "meta": { - "text": "match:case[0]-\u003e($secondLine4-\u003eprintln:data)", - "start": { "line": 62, "column": 14 }, - "stop": { "line": 62, "column": 60 } - } - }, - { - "normal": { - "senderSide": { - "literal": { - "value": { - "typeExpr": { - "inst": { - "ref": { - "name": "int", - "meta": { "start": {}, "stop": {} } - } - } - }, - "int": 0, - "meta": { - "text": "0", - "start": { "line": 63, "column": 8 }, - "stop": { "line": 63, "column": 8 } - } - }, - "meta": { "start": {}, "stop": {} } - }, - "meta": { - "text": "0", - "start": { "line": 63, "column": 8 }, - "stop": { "line": 63, "column": 8 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "match", - "port": "case", - "idx": 1, - "meta": { - "text": "match:case[1]", - "start": { "line": 63, "column": 14 }, - "stop": { "line": 63, "column": 26 } - } - }, - "meta": { "start": {}, "stop": {} } - } - ] - } - }, - "meta": { - "text": "match:case[1]-\u003e($secondLine3-\u003eprintln:data)", - "start": { "line": 63, "column": 14 }, - "stop": { "line": 63, "column": 60 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "match", - "port": "case", - "idx": 1, - "meta": { - "text": "match:case[1]", - "start": { "line": 63, "column": 14 }, - "stop": { "line": 63, "column": 26 } - } - }, - "meta": { - "text": "match:case[1]", - "start": { "line": 63, "column": 14 }, - "stop": { "line": 63, "column": 26 } - } - }, - "receiverSide": { - "deferredConnections": [ - { - "normal": { - "senderSide": { - "literal": { - "ref": { - "name": "secondLine3", - "meta": { - "text": "secondLine3", - "start": { "line": 63, "column": 33 }, - "stop": { "line": 63, "column": 33 } - } - }, - "meta": { "start": {}, "stop": {} } - }, - "meta": { - "text": "$secondLine3", - "start": { "line": 63, "column": 32 }, - "stop": { "line": 63, "column": 33 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "println", - "port": "data", - "meta": { - "text": "println:data", - "start": { "line": 63, "column": 48 }, - "stop": { "line": 63, "column": 56 } - } - }, - "meta": { - "text": "println:data", - "start": { "line": 63, "column": 48 }, - "stop": { "line": 63, "column": 56 } - } - } - ] - } - }, - "meta": { - "text": "$secondLine3-\u003eprintln:data", - "start": { "line": 63, "column": 32 }, - "stop": { "line": 63, "column": 56 } - } - } - ] - } - }, - "meta": { - "text": "match:case[1]-\u003e($secondLine3-\u003eprintln:data)", - "start": { "line": 63, "column": 14 }, - "stop": { "line": 63, "column": 60 } - } - }, - { - "normal": { - "senderSide": { - "literal": { - "value": { - "typeExpr": { - "inst": { - "ref": { - "name": "int", - "meta": { "start": {}, "stop": {} } - } - } - }, - "int": 1, - "meta": { - "text": "1", - "start": { "line": 64, "column": 8 }, - "stop": { "line": 64, "column": 8 } - } - }, - "meta": { "start": {}, "stop": {} } - }, - "meta": { - "text": "1", - "start": { "line": 64, "column": 8 }, - "stop": { "line": 64, "column": 8 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "match", - "port": "case", - "idx": 2, - "meta": { - "text": "match:case[2]", - "start": { "line": 64, "column": 14 }, - "stop": { "line": 64, "column": 26 } - } - }, - "meta": { "start": {}, "stop": {} } - } - ] - } - }, - "meta": { - "text": "match:case[2]-\u003e($secondLine2-\u003eprintln:data)", - "start": { "line": 64, "column": 14 }, - "stop": { "line": 64, "column": 60 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "match", - "port": "case", - "idx": 2, - "meta": { - "text": "match:case[2]", - "start": { "line": 64, "column": 14 }, - "stop": { "line": 64, "column": 26 } - } - }, - "meta": { - "text": "match:case[2]", - "start": { "line": 64, "column": 14 }, - "stop": { "line": 64, "column": 26 } - } - }, - "receiverSide": { - "deferredConnections": [ - { - "normal": { - "senderSide": { - "literal": { - "ref": { - "name": "secondLine2", - "meta": { - "text": "secondLine2", - "start": { "line": 64, "column": 33 }, - "stop": { "line": 64, "column": 33 } - } - }, - "meta": { "start": {}, "stop": {} } - }, - "meta": { - "text": "$secondLine2", - "start": { "line": 64, "column": 32 }, - "stop": { "line": 64, "column": 33 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "println", - "port": "data", - "meta": { - "text": "println:data", - "start": { "line": 64, "column": 48 }, - "stop": { "line": 64, "column": 56 } - } - }, - "meta": { - "text": "println:data", - "start": { "line": 64, "column": 48 }, - "stop": { "line": 64, "column": 56 } - } - } - ] - } - }, - "meta": { - "text": "$secondLine2-\u003eprintln:data", - "start": { "line": 64, "column": 32 }, - "stop": { "line": 64, "column": 56 } - } - } - ] - } - }, - "meta": { - "text": "match:case[2]-\u003e($secondLine2-\u003eprintln:data)", - "start": { "line": 64, "column": 14 }, - "stop": { "line": 64, "column": 60 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "match", - "port": "else", - "meta": { - "text": "match:else", - "start": { "line": 65, "column": 8 }, - "stop": { "line": 65, "column": 14 } - } - }, - "meta": { - "text": "match:else", - "start": { "line": 65, "column": 8 }, - "stop": { "line": 65, "column": 14 } - } - }, - "receiverSide": { - "deferredConnections": [ - { - "normal": { - "senderSide": { - "literal": { - "ref": { - "name": "secondLine1", - "meta": { - "text": "secondLine1", - "start": { "line": 67, "column": 14 }, - "stop": { "line": 67, "column": 14 } - } - }, - "meta": { "start": {}, "stop": {} } - }, - "meta": { - "text": "$secondLine1", - "start": { "line": 67, "column": 13 }, - "stop": { "line": 67, "column": 14 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "printf", - "port": "tpl", - "meta": { - "text": "printf:tpl", - "start": { "line": 67, "column": 29 }, - "stop": { "line": 67, "column": 36 } - } - }, - "meta": { - "text": "printf:tpl", - "start": { "line": 67, "column": 29 }, - "stop": { "line": 67, "column": 36 } - } - } - ] - } - }, - "meta": { - "text": "$secondLine1-\u003eprintf:tpl", - "start": { "line": 67, "column": 13 }, - "stop": { "line": 67, "column": 36 } - } - } - ], - "receivers": [ - { - "portAddr": { - "node": "printf", - "port": "args", - "idx": 0, - "meta": { - "text": "printf:args[0]", - "start": { "line": 66, "column": 12 }, - "stop": { "line": 66, "column": 25 } - } - }, - "meta": { - "text": "printf:args[0]", - "start": { "line": 66, "column": 12 }, - "stop": { "line": 66, "column": 25 } - } - } - ] - } - }, - "meta": { - "text": "match:else-\u003e[\nprintf:args[0],\n($secondLine1-\u003eprintf:tpl)\n]", - "start": { "line": 65, "column": 8 }, - "stop": { "line": 68, "column": 8 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "println", - "port": "sig", - "meta": { - "text": "println:sig", - "start": { "line": 70, "column": 9 }, - "stop": { "line": 70, "column": 17 } - } - }, - "meta": { - "text": "println:sig", - "start": { "line": 70, "column": 9 }, - "stop": { "line": 70, "column": 17 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "lock", - "port": "sig", - "meta": { - "text": "lock:sig", - "start": { "line": 70, "column": 41 }, - "stop": { "line": 70, "column": 46 } - } - }, - "meta": { - "text": "lock:sig", - "start": { "line": 70, "column": 41 }, - "stop": { "line": 70, "column": 46 } - } - } - ] - } - }, - "meta": { - "text": "[println:sig,printf:args[0]]-\u003elock:sig", - "start": { "line": 70, "column": 8 }, - "stop": { "line": 70, "column": 46 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "printf", - "port": "args", - "idx": 0, - "meta": { - "text": "printf:args[0]", - "start": { "line": 70, "column": 22 }, - "stop": { "line": 70, "column": 35 } - } - }, - "meta": { - "text": "printf:args[0]", - "start": { "line": 70, "column": 22 }, - "stop": { "line": 70, "column": 35 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "lock", - "port": "sig", - "meta": { - "text": "lock:sig", - "start": { "line": 70, "column": 41 }, - "stop": { "line": 70, "column": 46 } - } - }, - "meta": { - "text": "lock:sig", - "start": { "line": 70, "column": 41 }, - "stop": { "line": 70, "column": 46 } - } - } - ] - } - }, - "meta": { - "text": "[println:sig,printf:args[0]]-\u003elock:sig", - "start": { "line": 70, "column": 8 }, - "stop": { "line": 70, "column": 46 } - } - }, - { - "normal": { - "senderSide": { - "portAddr": { - "node": "lock", - "port": "data", - "meta": { - "text": "lock:data", - "start": { "line": 71, "column": 8 }, - "stop": { "line": 71, "column": 13 } - } - }, - "meta": { - "text": "lock:data", - "start": { "line": 71, "column": 8 }, - "stop": { "line": 71, "column": 13 } - } - }, - "receiverSide": { - "receivers": [ - { - "portAddr": { - "node": "out", - "port": "n", - "meta": { - "text": ":n", - "start": { "line": 71, "column": 21 }, - "stop": { "line": 71, "column": 22 } - } - }, - "meta": { - "text": ":n", - "start": { "line": 71, "column": 21 }, - "stop": { "line": 71, "column": 22 } - } - } - ] - } - }, - "meta": { - "text": "lock:data-\u003e:n", - "start": { "line": 71, "column": 8 }, - "stop": { "line": 71, "column": 22 } - } - } - ], - "meta": { "start": {}, "stop": {} } - } - }, - "firstLine1": { - "kind": "const_entity", - "const": { - "value": { - "typeExpr": { - "inst": { - "ref": { - "name": "string", - "meta": { - "text": "string", - "start": { "line": 26, "column": 15 }, - "stop": { "line": 26, "column": 15 } - } - } - }, - "meta": { - "text": "string", - "start": { "line": 26, "column": 15 }, - "stop": { "line": 26, "column": 15 } - } - }, - "str": "$0 bottles of beer on the wall, $0 bottles of beer.\n", - "meta": { - "text": "'$0 bottles of beer on the wall, $0 bottles of beer.\\n'", - "start": { "line": 26, "column": 24 }, - "stop": { "line": 26, "column": 24 } - } - }, - "meta": { - "text": "firstLine1string='$0 bottles of beer on the wall, $0 bottles of beer.\\n'\n", - "start": { "line": 26, "column": 4 }, - "stop": { "line": 26, "column": 79 } - } - }, - "type": {}, - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": {}, - "meta": { "start": {}, "stop": {} } - }, - "component": { - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": {}, - "meta": { "start": {}, "stop": {} } - }, - "meta": { "start": {}, "stop": {} } - } - }, - "firstLine2": { - "kind": "const_entity", - "const": { - "value": { - "typeExpr": { - "inst": { - "ref": { - "name": "string", - "meta": { - "text": "string", - "start": { "line": 27, "column": 15 }, - "stop": { "line": 27, "column": 15 } - } - } - }, - "meta": { - "text": "string", - "start": { "line": 27, "column": 15 }, - "stop": { "line": 27, "column": 15 } - } - }, - "str": "1 bottle of beer on the wall, 1 bottle of beer.", - "meta": { - "text": "'1 bottle of beer on the wall, 1 bottle of beer.'", - "start": { "line": 27, "column": 24 }, - "stop": { "line": 27, "column": 24 } - } - }, - "meta": { - "text": "firstLine2string='1 bottle of beer on the wall, 1 bottle of beer.'\n", - "start": { "line": 27, "column": 4 }, - "stop": { "line": 27, "column": 73 } - } - }, - "type": {}, - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": {}, - "meta": { "start": {}, "stop": {} } - }, - "component": { - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": {}, - "meta": { "start": {}, "stop": {} } - }, - "meta": { "start": {}, "stop": {} } - } - }, - "firstLine3": { - "kind": "const_entity", - "const": { - "value": { - "typeExpr": { - "inst": { - "ref": { - "name": "string", - "meta": { - "text": "string", - "start": { "line": 28, "column": 15 }, - "stop": { "line": 28, "column": 15 } - } - } - }, - "meta": { - "text": "string", - "start": { "line": 28, "column": 15 }, - "stop": { "line": 28, "column": 15 } - } - }, - "str": "No more bottles of beer on the wall, no more bottles of beer.", - "meta": { - "text": "'No more bottles of beer on the wall, no more bottles of beer.'", - "start": { "line": 28, "column": 24 }, - "stop": { "line": 28, "column": 24 } - } - }, - "meta": { - "text": "firstLine3string='No more bottles of beer on the wall, no more bottles of beer.'\n", - "start": { "line": 28, "column": 4 }, - "stop": { "line": 28, "column": 87 } - } - }, - "type": {}, - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": {}, - "meta": { "start": {}, "stop": {} } - }, - "component": { - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": {}, - "meta": { "start": {}, "stop": {} } - }, - "meta": { "start": {}, "stop": {} } - } - }, - "secondLine1": { - "kind": "const_entity", - "const": { - "value": { - "typeExpr": { - "inst": { - "ref": { - "name": "string", - "meta": { - "text": "string", - "start": { "line": 51, "column": 16 }, - "stop": { "line": 51, "column": 16 } - } - } - }, - "meta": { - "text": "string", - "start": { "line": 51, "column": 16 }, - "stop": { "line": 51, "column": 16 } - } - }, - "str": "Take one down and pass it around, $0 bottles of beer on the wall.\n\n", - "meta": { - "text": "'Take one down and pass it around, $0 bottles of beer on the wall.\\n\\n'", - "start": { "line": 51, "column": 25 }, - "stop": { "line": 51, "column": 25 } - } - }, - "meta": { - "text": "secondLine1string='Take one down and pass it around, $0 bottles of beer on the wall.\\n\\n'\n", - "start": { "line": 51, "column": 4 }, - "stop": { "line": 51, "column": 96 } - } - }, - "type": {}, - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": {}, - "meta": { "start": {}, "stop": {} } - }, - "component": { - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": {}, - "meta": { "start": {}, "stop": {} } - }, - "meta": { "start": {}, "stop": {} } - } - }, - "secondLine2": { - "kind": "const_entity", - "const": { - "value": { - "typeExpr": { - "inst": { - "ref": { - "name": "string", - "meta": { - "text": "string", - "start": { "line": 52, "column": 16 }, - "stop": { "line": 52, "column": 16 } - } - } - }, - "meta": { - "text": "string", - "start": { "line": 52, "column": 16 }, - "stop": { "line": 52, "column": 16 } - } - }, - "str": "Take one down and pass it around, 1 bottle of beer on the wall.\n", - "meta": { - "text": "'Take one down and pass it around, 1 bottle of beer on the wall.\\n'", - "start": { "line": 52, "column": 25 }, - "stop": { "line": 52, "column": 25 } - } - }, - "meta": { - "text": "secondLine2string='Take one down and pass it around, 1 bottle of beer on the wall.\\n'\n", - "start": { "line": 52, "column": 4 }, - "stop": { "line": 52, "column": 92 } - } - }, - "type": {}, - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": {}, - "meta": { "start": {}, "stop": {} } - }, - "component": { - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": {}, - "meta": { "start": {}, "stop": {} } - }, - "meta": { "start": {}, "stop": {} } - } - }, - "secondLine3": { - "kind": "const_entity", - "const": { - "value": { - "typeExpr": { - "inst": { - "ref": { - "name": "string", - "meta": { - "text": "string", - "start": { "line": 53, "column": 16 }, - "stop": { "line": 53, "column": 16 } - } - } - }, - "meta": { - "text": "string", - "start": { "line": 53, "column": 16 }, - "stop": { "line": 53, "column": 16 } - } - }, - "str": "Take one down and pass it around, no more bottles of beer on the wall.\n", - "meta": { - "text": "'Take one down and pass it around, no more bottles of beer on the wall.\\n'", - "start": { "line": 53, "column": 25 }, - "stop": { "line": 53, "column": 25 } - } - }, - "meta": { - "text": "secondLine3string='Take one down and pass it around, no more bottles of beer on the wall.\\n'\n", - "start": { "line": 53, "column": 4 }, - "stop": { "line": 53, "column": 99 } - } - }, - "type": {}, - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": {}, - "meta": { "start": {}, "stop": {} } - }, - "component": { - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": {}, - "meta": { "start": {}, "stop": {} } - }, - "meta": { "start": {}, "stop": {} } - } - }, - "secondLine4": { - "kind": "const_entity", - "const": { - "value": { - "typeExpr": { - "inst": { - "ref": { - "name": "string", - "meta": { - "text": "string", - "start": { "line": 54, "column": 16 }, - "stop": { "line": 54, "column": 16 } - } - } - }, - "meta": { - "text": "string", - "start": { "line": 54, "column": 16 }, - "stop": { "line": 54, "column": 16 } - } - }, - "str": "Go to the store and buy some more, 99 bottles of beer on the wall.", - "meta": { - "text": "'Go to the store and buy some more, 99 bottles of beer on the wall.'", - "start": { "line": 54, "column": 25 }, - "stop": { "line": 54, "column": 25 } - } - }, - "meta": { - "text": "secondLine4string='Go to the store and buy some more, 99 bottles of beer on the wall.'\n", - "start": { "line": 54, "column": 4 }, - "stop": { "line": 54, "column": 93 } - } - }, - "type": {}, - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": {}, - "meta": { "start": {}, "stop": {} } - }, - "component": { - "interface": { - "typeParams": { "meta": { "start": {}, "stop": {} } }, - "io": {}, - "meta": { "start": {}, "stop": {} } - }, - "meta": { "start": {}, "stop": {} } - } - } - } - } -} From 3f7f066866382d04105e8593e9d0972bafceca65 Mon Sep 17 00:00:00 2001 From: Emil Valeev Date: Mon, 29 Apr 2024 19:37:02 +0500 Subject: [PATCH 03/11] feat(stdlib): update after changing what stream item is (no more delimeters, last flag and index instead) --- internal/runtime/funcs/{mod.go => int_mod.go} | 0 internal/runtime/funcs/list_iter.go | 35 +++++++++++-------- .../runtime/funcs/{len.go => list_len.go} | 0 .../runtime/funcs/{push.go => list_push.go} | 0 internal/runtime/funcs/port_streamer.go | 19 ++++++---- internal/runtime/funcs/range.go | 32 ++++++++++++----- internal/runtime/funcs/registry.go | 4 +-- .../runtime/funcs/{join.go => string_join.go} | 0 .../funcs/{split.go => string_split.go} | 4 +-- internal/runtime/funcs/utils.go | 8 +++++ 10 files changed, 69 insertions(+), 33 deletions(-) rename internal/runtime/funcs/{mod.go => int_mod.go} (100%) rename internal/runtime/funcs/{len.go => list_len.go} (100%) rename internal/runtime/funcs/{push.go => list_push.go} (100%) rename internal/runtime/funcs/{join.go => string_join.go} (100%) rename internal/runtime/funcs/{split.go => string_split.go} (87%) diff --git a/internal/runtime/funcs/mod.go b/internal/runtime/funcs/int_mod.go similarity index 100% rename from internal/runtime/funcs/mod.go rename to internal/runtime/funcs/int_mod.go diff --git a/internal/runtime/funcs/list_iter.go b/internal/runtime/funcs/list_iter.go index 4a8820c1..372be673 100644 --- a/internal/runtime/funcs/list_iter.go +++ b/internal/runtime/funcs/list_iter.go @@ -8,7 +8,10 @@ import ( type list_iter struct{} -func (c list_iter) Create(io runtime.FuncIO, _ runtime.Msg) (func(ctx context.Context), error) { +func (c list_iter) Create( + io runtime.FuncIO, + _ runtime.Msg, +) (func(ctx context.Context), error) { dataIn, err := io.In.Port("data") if err != nil { return nil, err @@ -21,25 +24,27 @@ func (c list_iter) Create(io runtime.FuncIO, _ runtime.Msg) (func(ctx context.Co return func(ctx context.Context) { for { + var list []runtime.Msg + select { - case data, ok := <-dataIn: - if !ok { - return // lstIn channel closed - } - for i := 0; i < len(data.List()); i++ { - select { - case <-ctx.Done(): - return - case seqOut <- data.List()[i]: - } - } + case <-ctx.Done(): + return + case dataMsg := <-dataIn: + list = dataMsg.List() + } + + for idx := 0; idx < len(list); idx++ { + item := streamItem( + list[idx], + int64(idx), + idx == len(list)-1, + ) + select { case <-ctx.Done(): return - case seqOut <- nil: + case seqOut <- item: } - case <-ctx.Done(): - return } } }, nil diff --git a/internal/runtime/funcs/len.go b/internal/runtime/funcs/list_len.go similarity index 100% rename from internal/runtime/funcs/len.go rename to internal/runtime/funcs/list_len.go diff --git a/internal/runtime/funcs/push.go b/internal/runtime/funcs/list_push.go similarity index 100% rename from internal/runtime/funcs/push.go rename to internal/runtime/funcs/list_push.go diff --git a/internal/runtime/funcs/port_streamer.go b/internal/runtime/funcs/port_streamer.go index 2525d320..4bfd4704 100644 --- a/internal/runtime/funcs/port_streamer.go +++ b/internal/runtime/funcs/port_streamer.go @@ -7,9 +7,9 @@ import ( "github.com/nevalang/neva/internal/runtime" ) -type portSequencer struct{} +type portStreamer struct{} -func (portSequencer) Create( +func (portStreamer) Create( io runtime.FuncIO, _ runtime.Msg, ) (func(context.Context), error) { @@ -24,20 +24,27 @@ func (portSequencer) Create( } return func(ctx context.Context) { - var msg runtime.Msg - for { - for _, slot := range portIn { + l := len(portIn) + + for i, slot := range portIn { + var msg runtime.Msg select { case <-ctx.Done(): return case msg = <-slot: } + item := streamItem( + msg, + int64(i), + i == l-1, + ) + select { case <-ctx.Done(): return - case streamOut <- msg: + case streamOut <- item: } } diff --git a/internal/runtime/funcs/range.go b/internal/runtime/funcs/range.go index 47a4465e..d266e4e6 100644 --- a/internal/runtime/funcs/range.go +++ b/internal/runtime/funcs/range.go @@ -8,7 +8,10 @@ import ( type ranger struct{} -func (ranger) Create(io runtime.FuncIO, _ runtime.Msg) (func(ctx context.Context), error) { +func (ranger) Create( + io runtime.FuncIO, + _ runtime.Msg, +) (func(ctx context.Context), error) { fromIn, err := io.In.Port("from") if err != nil { return nil, err @@ -40,18 +43,31 @@ func (ranger) Create(io runtime.FuncIO, _ runtime.Msg) (func(ctx context.Context case toMsg = <-toIn: } - for i := fromMsg.Int(); i < toMsg.Int(); i++ { + var ( + idx int64 = 0 + last bool = false + data int64 = fromMsg.Int() + ) + + for !last { + if data == toMsg.Int()-1 { + last = true + } + + item := streamItem( + runtime.NewIntMsg(data), + idx, + last, + ) + select { case <-ctx.Done(): return - case dataOut <- runtime.NewIntMsg(i): + case dataOut <- item: } - } - select { - case <-ctx.Done(): - return - case dataOut <- nil: + idx++ + data++ } } }, nil diff --git a/internal/runtime/funcs/registry.go b/internal/runtime/funcs/registry.go index a0fbb4da..de3a6635 100644 --- a/internal/runtime/funcs/registry.go +++ b/internal/runtime/funcs/registry.go @@ -13,7 +13,7 @@ func CreatorRegistry() map[string]runtime.FuncCreator { "del": del{}, "lock": lock{}, "range": ranger{}, - "port_sequencer": portSequencer{}, + "port_sequencer": portStreamer{}, // structures "field": field{}, "struct_builder": structBuilder{}, @@ -46,7 +46,7 @@ func CreatorRegistry() map[string]runtime.FuncCreator { // time "time_sleep": timeSleep{}, //string - "split": split{}, + "split": stringSplit{}, // io/file "read_all": readAll{}, "write_all": writeAll{}, diff --git a/internal/runtime/funcs/join.go b/internal/runtime/funcs/string_join.go similarity index 100% rename from internal/runtime/funcs/join.go rename to internal/runtime/funcs/string_join.go diff --git a/internal/runtime/funcs/split.go b/internal/runtime/funcs/string_split.go similarity index 87% rename from internal/runtime/funcs/split.go rename to internal/runtime/funcs/string_split.go index ccb7c076..30e69b44 100644 --- a/internal/runtime/funcs/split.go +++ b/internal/runtime/funcs/string_split.go @@ -7,9 +7,9 @@ import ( "github.com/nevalang/neva/internal/runtime" ) -type split struct{} +type stringSplit struct{} -func (p split) Create(io runtime.FuncIO, _ runtime.Msg) (func(ctx context.Context), error) { +func (p stringSplit) Create(io runtime.FuncIO, _ runtime.Msg) (func(ctx context.Context), error) { dataIn, err := io.In.Port("data") if err != nil { return nil, err diff --git a/internal/runtime/funcs/utils.go b/internal/runtime/funcs/utils.go index 149f9fd9..94ba49a6 100644 --- a/internal/runtime/funcs/utils.go +++ b/internal/runtime/funcs/utils.go @@ -7,3 +7,11 @@ func errorFromString(s string) runtime.Msg { "text": runtime.NewStrMsg(s), }) } + +func streamItem(data runtime.Msg, idx int64, last bool) runtime.Msg { + return runtime.NewMapMsg(map[string]runtime.Msg{ + "data": data, + "idx": runtime.NewIntMsg(idx), + "last": runtime.NewBoolMsg(last), + }) +} From c74173ed1698786d141d5ce3686be62da7661758 Mon Sep 17 00:00:00 2001 From: Emil Valeev Date: Mon, 29 Apr 2024 20:38:07 +0500 Subject: [PATCH 04/11] fix(runtime:funcs): integer stream processors (math operators) updated for new stream API --- internal/runtime/funcs/int_add.go | 20 +++++++++++--------- internal/runtime/funcs/int_mul.go | 15 +++++++-------- internal/runtime/funcs/int_sub.go | 21 +++++++++++---------- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/internal/runtime/funcs/int_add.go b/internal/runtime/funcs/int_add.go index d02e984c..8c870894 100644 --- a/internal/runtime/funcs/int_add.go +++ b/internal/runtime/funcs/int_add.go @@ -8,7 +8,10 @@ import ( type intAdd struct{} -func (intAdd) Create(io runtime.FuncIO, _ runtime.Msg) (func(ctx context.Context), error) { +func (intAdd) Create( + io runtime.FuncIO, + _ runtime.Msg, +) (func(ctx context.Context), error) { seqIn, err := io.In.Port("seq") if err != nil { return nil, err @@ -20,29 +23,28 @@ func (intAdd) Create(io runtime.FuncIO, _ runtime.Msg) (func(ctx context.Context } return func(ctx context.Context) { - var ( - acc int64 - cur runtime.Msg - ) + var acc int64 = 0 for { + var item map[string]runtime.Msg select { case <-ctx.Done(): return - case cur = <-seqIn: + case msg := <-seqIn: + item = msg.Map() } - if cur == nil { + if item["last"].Bool() { select { case <-ctx.Done(): return case resOut <- runtime.NewIntMsg(acc): - acc = 0 + acc = 0 // reset continue } } - acc += cur.Int() + acc += item["data"].Int() } }, nil } diff --git a/internal/runtime/funcs/int_mul.go b/internal/runtime/funcs/int_mul.go index 385869c9..cb8f8a9a 100644 --- a/internal/runtime/funcs/int_mul.go +++ b/internal/runtime/funcs/int_mul.go @@ -20,29 +20,28 @@ func (intMul) Create(io runtime.FuncIO, _ runtime.Msg) (func(ctx context.Context } return func(ctx context.Context) { - var ( - acc int64 = 1 - cur runtime.Msg - ) + var acc int64 = 1 for { + var item map[string]runtime.Msg select { case <-ctx.Done(): return - case cur = <-seqIn: + case msg := <-seqIn: + item = msg.Map() } - if cur == nil { + if item["last"].Bool() { select { case <-ctx.Done(): return case resOut <- runtime.NewIntMsg(acc): - acc = 1 + acc = 1 // reset continue } } - acc *= cur.Int() + acc *= item["data"].Int() } }, nil } diff --git a/internal/runtime/funcs/int_sub.go b/internal/runtime/funcs/int_sub.go index 90ab21e9..14e5097c 100644 --- a/internal/runtime/funcs/int_sub.go +++ b/internal/runtime/funcs/int_sub.go @@ -21,34 +21,35 @@ func (intSub) Create(io runtime.FuncIO, _ runtime.Msg) (func(ctx context.Context return func(ctx context.Context) { var ( - acc int64 = 0 - inProgress bool = false - cur runtime.Msg + acc int64 = 0 + started bool = false ) for { + var item map[string]runtime.Msg select { case <-ctx.Done(): return - case cur = <-seqIn: + case msg := <-seqIn: + item = msg.Map() } - if cur == nil { + if item["last"].Bool() { select { case <-ctx.Done(): return case resOut <- runtime.NewIntMsg(acc): acc = 0 - inProgress = false + started = false continue } } - if !inProgress { - acc = cur.Int() - inProgress = true + if !started { + acc = item["data"].Int() + started = true } else { - acc -= cur.Int() + acc -= item["data"].Int() } } }, nil From 1610f08cbae198dc7e938c1ec2236c255b4e1a17 Mon Sep 17 00:00:00 2001 From: Emil Valeev Date: Mon, 29 Apr 2024 20:49:44 +0500 Subject: [PATCH 05/11] fix(std:runtime/funcs): int ops --- .vscode/launch.json | 2 +- internal/runtime/funcs/int_add.go | 3 ++- internal/runtime/funcs/int_mul.go | 4 ++-- internal/runtime/funcs/int_sub.go | 14 +++++++------- internal/runtime/funcs/port_streamer.go | 6 ------ 5 files changed, 12 insertions(+), 17 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 1876af71..9fa2d6bb 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -17,7 +17,7 @@ "mode": "auto", "program": "${workspaceFolder}/cmd/neva", "cwd": "${workspaceFolder}", - "args": ["run", "examples/struct_selector"] + "args": ["run", "e2e/add_nums_verbose/main"] }, { "name": "LSP", diff --git a/internal/runtime/funcs/int_add.go b/internal/runtime/funcs/int_add.go index 8c870894..f1d82e4b 100644 --- a/internal/runtime/funcs/int_add.go +++ b/internal/runtime/funcs/int_add.go @@ -34,6 +34,8 @@ func (intAdd) Create( item = msg.Map() } + acc += item["data"].Int() + if item["last"].Bool() { select { case <-ctx.Done(): @@ -44,7 +46,6 @@ func (intAdd) Create( } } - acc += item["data"].Int() } }, nil } diff --git a/internal/runtime/funcs/int_mul.go b/internal/runtime/funcs/int_mul.go index cb8f8a9a..ee6e32fd 100644 --- a/internal/runtime/funcs/int_mul.go +++ b/internal/runtime/funcs/int_mul.go @@ -31,6 +31,8 @@ func (intMul) Create(io runtime.FuncIO, _ runtime.Msg) (func(ctx context.Context item = msg.Map() } + acc *= item["data"].Int() + if item["last"].Bool() { select { case <-ctx.Done(): @@ -40,8 +42,6 @@ func (intMul) Create(io runtime.FuncIO, _ runtime.Msg) (func(ctx context.Context continue } } - - acc *= item["data"].Int() } }, nil } diff --git a/internal/runtime/funcs/int_sub.go b/internal/runtime/funcs/int_sub.go index 14e5097c..a4a13598 100644 --- a/internal/runtime/funcs/int_sub.go +++ b/internal/runtime/funcs/int_sub.go @@ -34,6 +34,13 @@ func (intSub) Create(io runtime.FuncIO, _ runtime.Msg) (func(ctx context.Context item = msg.Map() } + if !started { + acc = item["data"].Int() + started = true + } else { + acc -= item["data"].Int() + } + if item["last"].Bool() { select { case <-ctx.Done(): @@ -44,13 +51,6 @@ func (intSub) Create(io runtime.FuncIO, _ runtime.Msg) (func(ctx context.Context continue } } - - if !started { - acc = item["data"].Int() - started = true - } else { - acc -= item["data"].Int() - } } }, nil } diff --git a/internal/runtime/funcs/port_streamer.go b/internal/runtime/funcs/port_streamer.go index 4bfd4704..e12c4f62 100644 --- a/internal/runtime/funcs/port_streamer.go +++ b/internal/runtime/funcs/port_streamer.go @@ -47,12 +47,6 @@ func (portStreamer) Create( case streamOut <- item: } } - - select { - case <-ctx.Done(): - return - case streamOut <- nil: - } } }, nil } From 1ebdf72775a9fbbf9d423476ac86ae903b26789c Mon Sep 17 00:00:00 2001 From: Emil Valeev Date: Mon, 29 Apr 2024 21:00:16 +0500 Subject: [PATCH 06/11] wip(examples): fixing examples after updating how streams works --- examples/fizzbuzz/main.neva | 8 +++----- examples/iterate_over_list/main.neva | 7 ++++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/examples/fizzbuzz/main.neva b/examples/fizzbuzz/main.neva index b8207efd..1f7ad4e3 100644 --- a/examples/fizzbuzz/main.neva +++ b/examples/fizzbuzz/main.neva @@ -1,20 +1,18 @@ component Main(start) (stop) { - nodes { Mod, Range, Match, Unwrap, Println, Lock } + nodes { Mod, Range, Match, Println } net { :start -> [ (1 -> range:from), (101 -> range:to) ] - range -> unwrap - unwrap:some -> [mod:data, lock:data] + range.data -> mod:data 15 -> mod:case[0] -> ('FizzBuzz' -> println) 3 -> mod:case[1] -> ('Fizz' -> println) 5 -> mod:case[2] -> ('Buzz' -> println) mod:else -> println - println -> lock:sig - lock -> match:data + println -> match:data 100 -> match:case[0] -> :stop } } diff --git a/examples/iterate_over_list/main.neva b/examples/iterate_over_list/main.neva index 898034cd..b32025ee 100644 --- a/examples/iterate_over_list/main.neva +++ b/examples/iterate_over_list/main.neva @@ -1,9 +1,10 @@ const lst list = [50, 30, 20, 100] component Main(start) (stop) { - nodes { Println>, Iter, Unwrap } + nodes { Println>, Iter, Match } net { - :start -> ($lst -> iter -> println -> unwrap) - unwrap:none -> :stop + :start -> ($lst -> iter -> println) + println.last -> match:data + true -> match:case[0] -> :stop } } \ No newline at end of file From 984696572031d557adef953555dd795d585971f1 Mon Sep 17 00:00:00 2001 From: Emil Valeev Date: Mon, 29 Apr 2024 21:05:33 +0500 Subject: [PATCH 07/11] fix(examples): fizzbuzz working now --- examples/fizzbuzz/main.neva | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/examples/fizzbuzz/main.neva b/examples/fizzbuzz/main.neva index 1f7ad4e3..c4543539 100644 --- a/examples/fizzbuzz/main.neva +++ b/examples/fizzbuzz/main.neva @@ -1,18 +1,26 @@ component Main(start) (stop) { - nodes { Mod, Range, Match, Println } + nodes { Range, PrintLine, Match } net { :start -> [ (1 -> range:from), (101 -> range:to) ] + range.data -> printLine -> match:data + 100 -> match:case[0] -> :stop + } +} + +component PrintLine(data int) (data int) { + nodes { Mod, Println, Lock } + net { + :data -> [mod:data, lock:data] - range.data -> mod:data 15 -> mod:case[0] -> ('FizzBuzz' -> println) 3 -> mod:case[1] -> ('Fizz' -> println) 5 -> mod:case[2] -> ('Buzz' -> println) mod:else -> println - println -> match:data - 100 -> match:case[0] -> :stop + println -> lock:sig + lock:data -> :data } -} +} \ No newline at end of file From c97973cbb241eb15279824590142b273e720737b Mon Sep 17 00:00:00 2001 From: Emil Valeev Date: Mon, 29 Apr 2024 21:27:30 +0500 Subject: [PATCH 08/11] feat(runtime:msg:printing): implement json.Marshal for message printing (repr) --- examples/iterate_over_list/e2e_test.go | 6 +++- internal/runtime/msg.go | 50 +++++++++++++++++--------- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/examples/iterate_over_list/e2e_test.go b/examples/iterate_over_list/e2e_test.go index 05862cea..b4880414 100644 --- a/examples/iterate_over_list/e2e_test.go +++ b/examples/iterate_over_list/e2e_test.go @@ -22,7 +22,11 @@ func Test(t *testing.T) { require.NoError(t, err) require.Equal( t, - "50\n30\n20\n100\n\n", + `{"data": 50, "idx": 0, "last": false} +{"data": 30, "idx": 1, "last": false} +{"data": 20, "idx": 2, "last": false} +{"data": 100, "idx": 3, "last": true} +`, string(out), ) diff --git a/internal/runtime/msg.go b/internal/runtime/msg.go index 8194e4b8..5d94d6fc 100644 --- a/internal/runtime/msg.go +++ b/internal/runtime/msg.go @@ -1,8 +1,10 @@ package runtime import ( + "encoding/json" "fmt" "strconv" + "strings" ) // Msg methods don't return errors because they can be used not only at startup. @@ -50,9 +52,10 @@ type IntMsg struct { v int64 } -func (msg IntMsg) Type() MsgType { return IntMsgType } -func (msg IntMsg) Int() int64 { return msg.v } -func (msg IntMsg) String() string { return strconv.Itoa(int(msg.v)) } +func (msg IntMsg) Type() MsgType { return IntMsgType } +func (msg IntMsg) Int() int64 { return msg.v } +func (msg IntMsg) String() string { return strconv.Itoa(int(msg.v)) } +func (msg IntMsg) MarshalJSON() ([]byte, error) { return []byte(msg.String()), nil } func NewIntMsg(n int64) IntMsg { return IntMsg{ @@ -68,9 +71,10 @@ type FloatMsg struct { v float64 } -func (msg FloatMsg) Type() MsgType { return FloatMsgType } -func (msg FloatMsg) Float() float64 { return msg.v } -func (msg FloatMsg) String() string { return fmt.Sprint(msg.v) } +func (msg FloatMsg) Type() MsgType { return FloatMsgType } +func (msg FloatMsg) Float() float64 { return msg.v } +func (msg FloatMsg) String() string { return fmt.Sprint(msg.v) } +func (msg FloatMsg) MarshalJSON() ([]byte, error) { return []byte(msg.String()), nil } func NewFloatMsg(n float64) FloatMsg { return FloatMsg{ @@ -86,9 +90,10 @@ type StrMsg struct { v string } -func (msg StrMsg) Type() MsgType { return StrMsgType } -func (msg StrMsg) Str() string { return msg.v } -func (msg StrMsg) String() string { return msg.v } +func (msg StrMsg) Type() MsgType { return StrMsgType } +func (msg StrMsg) Str() string { return msg.v } +func (msg StrMsg) String() string { return msg.v } +func (msg StrMsg) MarshalJSON() ([]byte, error) { return []byte(msg.String()), nil } func NewStrMsg(s string) StrMsg { return StrMsg{ @@ -104,9 +109,10 @@ type BoolMsg struct { v bool } -func (msg BoolMsg) Type() MsgType { return BoolMsgType } -func (msg BoolMsg) Bool() bool { return msg.v } -func (msg BoolMsg) String() string { return strconv.FormatBool(msg.v) } +func (msg BoolMsg) Type() MsgType { return BoolMsgType } +func (msg BoolMsg) Bool() bool { return msg.v } +func (msg BoolMsg) String() string { return strconv.FormatBool(msg.v) } +func (msg BoolMsg) MarshalJSON() ([]byte, error) { return []byte(msg.String()), nil } func NewBoolMsg(b bool) BoolMsg { return BoolMsg{ @@ -121,9 +127,10 @@ type ListMsg struct { v []Msg } -func (msg ListMsg) Type() MsgType { return ListMsgType } -func (msg ListMsg) List() []Msg { return msg.v } -func (msg ListMsg) String() string { return fmt.Sprint(msg.v) } +func (msg ListMsg) Type() MsgType { return ListMsgType } +func (msg ListMsg) List() []Msg { return msg.v } +func (msg ListMsg) String() string { return fmt.Sprint(msg.v) } +func (msg ListMsg) MarshalJSON() ([]byte, error) { return []byte(msg.String()), nil } func NewListMsg(v ...Msg) ListMsg { return ListMsg{ @@ -140,7 +147,18 @@ type MapMsg struct { func (msg MapMsg) Type() MsgType { return MapMsgType } func (msg MapMsg) Map() map[string]Msg { return msg.v } -func (msg MapMsg) String() string { return fmt.Sprint(msg.v) } +func (msg MapMsg) String() string { + jsonData, err := json.Marshal(msg.v) + if err != nil { + panic(err) + } + + jsonString := string(jsonData) + jsonString = strings.ReplaceAll(jsonString, ":", ": ") + jsonString = strings.ReplaceAll(jsonString, ",", ", ") + + return jsonString +} func NewMapMsg(m map[string]Msg) MapMsg { return MapMsg{ From 54b9d87a52eb789b3284d9a966d55780ab6821c3 Mon Sep 17 00:00:00 2001 From: Emil Valeev Date: Mon, 29 Apr 2024 21:42:18 +0500 Subject: [PATCH 09/11] fix(runtime:msg): fix json.Marshal for ListMsg type --- internal/runtime/msg.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/runtime/msg.go b/internal/runtime/msg.go index 5d94d6fc..fd2fe37a 100644 --- a/internal/runtime/msg.go +++ b/internal/runtime/msg.go @@ -130,7 +130,7 @@ type ListMsg struct { func (msg ListMsg) Type() MsgType { return ListMsgType } func (msg ListMsg) List() []Msg { return msg.v } func (msg ListMsg) String() string { return fmt.Sprint(msg.v) } -func (msg ListMsg) MarshalJSON() ([]byte, error) { return []byte(msg.String()), nil } +func (msg ListMsg) MarshalJSON() ([]byte, error) { return json.Marshal(msg.v) } func NewListMsg(v ...Msg) ListMsg { return ListMsg{ From 75407f6ea464febb49831c92febb8d815474c0e5 Mon Sep 17 00:00:00 2001 From: Emil Valeev Date: Mon, 29 Apr 2024 21:52:50 +0500 Subject: [PATCH 10/11] fix(e2e): const refs --- e2e/const_refs_verbose/e2e_test.go | 6 +++++- e2e/const_refs_verbose/main/main.neva | 6 +----- internal/runtime/msg.go | 11 +++++++++-- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/e2e/const_refs_verbose/e2e_test.go b/e2e/const_refs_verbose/e2e_test.go index 7b5d1a1a..29aec5b6 100644 --- a/e2e/const_refs_verbose/e2e_test.go +++ b/e2e/const_refs_verbose/e2e_test.go @@ -7,14 +7,18 @@ import ( "github.com/stretchr/testify/require" ) +// Nested map has only one key because keys are unordered +// so having order in test will make it flacky. func Test(t *testing.T) { cmd := exec.Command("neva", "run", "main") out, err := cmd.CombinedOutput() require.NoError(t, err) + require.Equal( t, - "map[l:[1 2 3] m:map[one:1 three:3 two:2]]\n", + `{"l": [1, 2, 3], "m": {"key": 1}} +`, string(out), ) diff --git a/e2e/const_refs_verbose/main/main.neva b/e2e/const_refs_verbose/main/main.neva index 0fbb71aa..c8bfbbe3 100644 --- a/e2e/const_refs_verbose/main/main.neva +++ b/e2e/const_refs_verbose/main/main.neva @@ -8,11 +8,7 @@ const { two int = 2 three int = 3 numsList list = [one, two, three] - numsMap map = { - one: one, - two: two, - three: three - } + numsMap map = { key: one } numsStruct NumsStruct = { l: numsList, m: numsMap diff --git a/internal/runtime/msg.go b/internal/runtime/msg.go index fd2fe37a..1da4e7c6 100644 --- a/internal/runtime/msg.go +++ b/internal/runtime/msg.go @@ -147,7 +147,7 @@ type MapMsg struct { func (msg MapMsg) Type() MsgType { return MapMsgType } func (msg MapMsg) Map() map[string]Msg { return msg.v } -func (msg MapMsg) String() string { +func (msg MapMsg) MarshalJSON() ([]byte, error) { jsonData, err := json.Marshal(msg.v) if err != nil { panic(err) @@ -157,7 +157,14 @@ func (msg MapMsg) String() string { jsonString = strings.ReplaceAll(jsonString, ":", ": ") jsonString = strings.ReplaceAll(jsonString, ",", ", ") - return jsonString + return []byte(jsonString), nil +} +func (msg MapMsg) String() string { + b, err := msg.MarshalJSON() + if err != nil { + panic(err) + } + return string(b) } func NewMapMsg(m map[string]Msg) MapMsg { From 35ee82e3cf172191391b545f63082b258dcfb18d Mon Sep 17 00:00:00 2001 From: Emil Valeev Date: Mon, 29 Apr 2024 21:58:01 +0500 Subject: [PATCH 11/11] fix(examples:constRefs) --- examples/const_refs/e2e_test.go | 5 ++++- examples/const_refs/main.neva | 6 +----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/examples/const_refs/e2e_test.go b/examples/const_refs/e2e_test.go index c26962ea..7e984401 100644 --- a/examples/const_refs/e2e_test.go +++ b/examples/const_refs/e2e_test.go @@ -8,6 +8,8 @@ import ( "github.com/stretchr/testify/require" ) +// Nested map has only one key because keys are unordered +// so having order in test will make it flacky. func Test(t *testing.T) { err := os.Chdir("..") require.NoError(t, err) @@ -22,7 +24,8 @@ func Test(t *testing.T) { require.NoError(t, err) require.Equal( t, - "map[l:[1 2 3] m:map[one:1 three:3 two:2]]\n", + `{"l": [1, 2, 3], "m": {"key": 1}} +`, string(out), ) diff --git a/examples/const_refs/main.neva b/examples/const_refs/main.neva index 22eb05a9..f56042c9 100644 --- a/examples/const_refs/main.neva +++ b/examples/const_refs/main.neva @@ -8,11 +8,7 @@ const { two int = 2 three int = 3 numsList list = [one, two, three] - numsMap map = { - one: one, - two: two, - three: three - } + numsMap map = { key: one } numsStruct NumsStruct = { l: numsList, m: numsMap