From 4fc94b1e091dd1aaf04e28013b35d89511c6d9c4 Mon Sep 17 00:00:00 2001 From: s-ol Date: Sat, 1 May 2021 20:03:01 +0200 Subject: rename array/struct modules to avoid name conflict --- alv-lib/array-.moon | 297 +++++++++++++++++++++++++++++++++++++++++++++ alv-lib/array.moon | 297 --------------------------------------------- alv-lib/struct-.moon | 129 ++++++++++++++++++++ alv-lib/struct.moon | 129 -------------------- spec/lang/array_spec.moon | 2 +- spec/lang/struct_spec.moon | 2 +- 6 files changed, 428 insertions(+), 428 deletions(-) create mode 100644 alv-lib/array-.moon delete mode 100644 alv-lib/array.moon create mode 100644 alv-lib/struct-.moon delete mode 100644 alv-lib/struct.moon diff --git a/alv-lib/array-.moon b/alv-lib/array-.moon new file mode 100644 index 0000000..aeb6820 --- /dev/null +++ b/alv-lib/array-.moon @@ -0,0 +1,297 @@ +import Array, Op, PureOp, Builtin, Constant, Error, const, sig, evt, T from require 'alv.base' +import Cell from require 'alv.cell' +import Tag from require 'alv.tag' +builtins = require 'alv.builtins' + +unpack or= table.unpack +any = sig! / evt! + +get = Constant.meta + meta: + name: 'get' + summary: "Index into an array." + examples: { '(get array i)' } + description: "Get the value at index `i` (starting at 0). + +`i` has to be a constant expression." + + value: class extends PureOp + pattern: any + const.num + type: (inputs) => + { array, i } = inputs + array\type!\get i.result! + + tick: => + { array, i } = @unwrap_all! + @out\set array[i + 1] + +set = Constant.meta + meta: + name: 'set' + summary: "Update a value in an array." + examples: { '(set array i val)' } + description: "Set the value for `i` to `val`. + +`i` has to be a constant expression. This is a pure op, so at most one of +`array` and `val` may be a !-stream." + + value: class extends PureOp + pattern: any + const.num + any + type: (inputs) => + { array, i, val } = inputs + type = array\type! + expected = type\get i.result! + + if expected ~= val\type! + msg = string.format "expected value of type %s, not %s", + expected, val\type! + error Error 'argument', msg + + type + + tick: => + { array, key, val } = @unwrap_all! + + array = [v for v in *array] + array[key + 1] = val + + @out\set array + +head = Constant.meta + meta: + name: 'head' + summary: "Get the first element from an array." + examples: { '(head array)' } + + value: class extends PureOp + pattern: any*1 + type: (inputs) => + type = inputs[1]\type! + + assert type.__class == Array, Error 'argument', "expected an Array" + assert type.size > 0, Error 'argument', "cannot get head of empty Array" + + type.type + + tick: => + { array } = @unwrap_all! + @out\set array[1] + +tail = Constant.meta + meta: + name: 'tail' + summary: "Get everything except the first element from an array." + examples: { '(tail array)' } + + value: class extends PureOp + pattern: any*1 + type: (inputs) => + type = inputs[1]\type! + + assert type.__class == Array, Error 'argument', "expected an Array" + assert type.size > 0, Error 'argument', "cannot get tail of empty Array" + + Array type.size - 1, type.type + + tick: => + { array } = @unwrap_all! + @out\set [v for v in *array[2,]] + +prepend = Constant.meta + meta: + name: 'prepend' + summary: "Prepend a new value at the start of an array." + examples: { '(prepend array val)' } + description: "Prepend `val` to `array` at index `0`, moving other values back. + +This is a pure op, so at most one of `array` and `val` may be a !-stream." + + value: class extends PureOp + pattern: any + any + type: (inputs) => + { array, val } = inputs + type = array\type! + + if val\type! ~= type.type + msg = string.format "expected value of type %s, not %s", + type.type, val\type! + error Error 'argument', msg + + Array type.size + 1, type.type + + tick: => + { array, val } = @unwrap_all! + + array = [v for v in *array] + table.insert array, 1, val + + @out\set array + +insert = Constant.meta + meta: + name: 'insert' + summary: "Insert a new value into an array." + examples: { '(insert array i val)' } + description: "Insert `val` into `array` at `i`, moving other values back if +necessary. + +`i` has to be a constant expression. This is a pure op, so at most one of +`array` and `val` may be a !-stream." + + value: class extends PureOp + pattern: any + const.num + any + type: (inputs) => + { array, i, val } = inputs + type = array\type! + i = i.result! + + if i > type.size or i < 0 + error Error 'argument', "index '#{i}' out of range!" + if val\type! ~= type.type + msg = string.format "expected value of type %s, not %s", + type.type, val\type! + error Error 'argument', msg + + Array type.size + 1, type.type + + tick: => + { array, i, val } = @unwrap_all! + + array = [v for v in *array] + table.insert array, i + 1, val + + @out\set array + +remove = Constant.meta + meta: + name: 'remove' + summary: "Remove a value from an Array." + examples: { '(remove array i)' } + description: "Removes the value at index `i` from `array`. + +`i` has to be a constant expression." + + value: class extends PureOp + pattern: any + const.num + type: (inputs) => + { array, i } = inputs + type = array\type! + + -- check index range + type\get i.result! + + Array type.size - 1, type.type + + tick: => + { array, i, val } = @unwrap_all! + + array = [v for v in *array] + table.remove array, i + 1 + + @out\set array + +size = Constant.meta + meta: + name: 'size' + summary: "Get the size of an array." + examples: { '(size array)' } + + value: class extends Op + setup: (inputs) => + super {} + + assert #inputs == 1, Error 'argument', "expected exactly one argument" + type = inputs[1]\type! + assert type.__class == Array, Error 'argument', "expected an Array" + + @out = Constant.num type.size + +concat = Constant.meta + meta: + name: 'concat' + summary: "Concatenate Arrays." + examples: { '(concat arr1 arr2 [arr3…])' } + + value: class extends PureOp + pattern: any\rep 2 + type: (inputs) => + size = 0 + type = inputs[1]\type!.type + + for input in *inputs + array = input\type! + + if array.type ~= type + msg = string.format "Cannot concatenate different arrays %s, %s", + inputs[1]\type!, array + error Error 'argument', msg + + size += array.size + + Array size, type + + tick: => + arrays = @unwrap_all! + out = {} + + for array in *arrays + for val in *array + table.insert out, val + + @out\set out + +array_constr = builtins!\get('array').result +map = Constant.meta + meta: + name: 'map' + summary: "Apply an function to each value in an array." + examples: { '(map array fn)' } + description: " +Invokes `fn` once for each element in `array` and returns an array of the results. +`fn` must take one argument and return the same type consistently." + + value: class extends Builtin + eval: (scope, tail) => + L\trace "evaling #{@}" + assert #tail == 2, "'map' takes exactly two arguments" + tail = [L\push t\eval, scope for t in *tail] + { array, fn } = tail + + fndef = fn.result + assert fn\type! == T.fndef, "fn has to be a fndef" + array_type = array\type! + assert array_type.__class == Array, Error 'argument', "expected an Array" + + invocations = for i=1, array_type.size + tag_o = @tag\clone Tag.parse tostring i + tag_i = @tag\clone tag_o + Cell tag_o, { + with Constant.literal T.fndef, fndef!, 'fn' + .meta = fndef.meta + Cell tag_i, { + Constant.literal T.opdef, get!, 'get' + Constant.literal array_type, array.result!, 'array' + Constant.num i-1 + } + } + + tag = @tag\clone Tag.parse '-1' + inner = Cell tag, { + Constant.literal T.opdef, array_constr, 'array' + unpack invocations + } + super inner\eval scope + + +Constant.meta + meta: + name: 'array' + summary: "Utilities for dealing with arrays." + + value: + :get, :set + :head, :tail, :prepend + :insert, :remove + :map + + :size, :concat diff --git a/alv-lib/array.moon b/alv-lib/array.moon deleted file mode 100644 index aeb6820..0000000 --- a/alv-lib/array.moon +++ /dev/null @@ -1,297 +0,0 @@ -import Array, Op, PureOp, Builtin, Constant, Error, const, sig, evt, T from require 'alv.base' -import Cell from require 'alv.cell' -import Tag from require 'alv.tag' -builtins = require 'alv.builtins' - -unpack or= table.unpack -any = sig! / evt! - -get = Constant.meta - meta: - name: 'get' - summary: "Index into an array." - examples: { '(get array i)' } - description: "Get the value at index `i` (starting at 0). - -`i` has to be a constant expression." - - value: class extends PureOp - pattern: any + const.num - type: (inputs) => - { array, i } = inputs - array\type!\get i.result! - - tick: => - { array, i } = @unwrap_all! - @out\set array[i + 1] - -set = Constant.meta - meta: - name: 'set' - summary: "Update a value in an array." - examples: { '(set array i val)' } - description: "Set the value for `i` to `val`. - -`i` has to be a constant expression. This is a pure op, so at most one of -`array` and `val` may be a !-stream." - - value: class extends PureOp - pattern: any + const.num + any - type: (inputs) => - { array, i, val } = inputs - type = array\type! - expected = type\get i.result! - - if expected ~= val\type! - msg = string.format "expected value of type %s, not %s", - expected, val\type! - error Error 'argument', msg - - type - - tick: => - { array, key, val } = @unwrap_all! - - array = [v for v in *array] - array[key + 1] = val - - @out\set array - -head = Constant.meta - meta: - name: 'head' - summary: "Get the first element from an array." - examples: { '(head array)' } - - value: class extends PureOp - pattern: any*1 - type: (inputs) => - type = inputs[1]\type! - - assert type.__class == Array, Error 'argument', "expected an Array" - assert type.size > 0, Error 'argument', "cannot get head of empty Array" - - type.type - - tick: => - { array } = @unwrap_all! - @out\set array[1] - -tail = Constant.meta - meta: - name: 'tail' - summary: "Get everything except the first element from an array." - examples: { '(tail array)' } - - value: class extends PureOp - pattern: any*1 - type: (inputs) => - type = inputs[1]\type! - - assert type.__class == Array, Error 'argument', "expected an Array" - assert type.size > 0, Error 'argument', "cannot get tail of empty Array" - - Array type.size - 1, type.type - - tick: => - { array } = @unwrap_all! - @out\set [v for v in *array[2,]] - -prepend = Constant.meta - meta: - name: 'prepend' - summary: "Prepend a new value at the start of an array." - examples: { '(prepend array val)' } - description: "Prepend `val` to `array` at index `0`, moving other values back. - -This is a pure op, so at most one of `array` and `val` may be a !-stream." - - value: class extends PureOp - pattern: any + any - type: (inputs) => - { array, val } = inputs - type = array\type! - - if val\type! ~= type.type - msg = string.format "expected value of type %s, not %s", - type.type, val\type! - error Error 'argument', msg - - Array type.size + 1, type.type - - tick: => - { array, val } = @unwrap_all! - - array = [v for v in *array] - table.insert array, 1, val - - @out\set array - -insert = Constant.meta - meta: - name: 'insert' - summary: "Insert a new value into an array." - examples: { '(insert array i val)' } - description: "Insert `val` into `array` at `i`, moving other values back if -necessary. - -`i` has to be a constant expression. This is a pure op, so at most one of -`array` and `val` may be a !-stream." - - value: class extends PureOp - pattern: any + const.num + any - type: (inputs) => - { array, i, val } = inputs - type = array\type! - i = i.result! - - if i > type.size or i < 0 - error Error 'argument', "index '#{i}' out of range!" - if val\type! ~= type.type - msg = string.format "expected value of type %s, not %s", - type.type, val\type! - error Error 'argument', msg - - Array type.size + 1, type.type - - tick: => - { array, i, val } = @unwrap_all! - - array = [v for v in *array] - table.insert array, i + 1, val - - @out\set array - -remove = Constant.meta - meta: - name: 'remove' - summary: "Remove a value from an Array." - examples: { '(remove array i)' } - description: "Removes the value at index `i` from `array`. - -`i` has to be a constant expression." - - value: class extends PureOp - pattern: any + const.num - type: (inputs) => - { array, i } = inputs - type = array\type! - - -- check index range - type\get i.result! - - Array type.size - 1, type.type - - tick: => - { array, i, val } = @unwrap_all! - - array = [v for v in *array] - table.remove array, i + 1 - - @out\set array - -size = Constant.meta - meta: - name: 'size' - summary: "Get the size of an array." - examples: { '(size array)' } - - value: class extends Op - setup: (inputs) => - super {} - - assert #inputs == 1, Error 'argument', "expected exactly one argument" - type = inputs[1]\type! - assert type.__class == Array, Error 'argument', "expected an Array" - - @out = Constant.num type.size - -concat = Constant.meta - meta: - name: 'concat' - summary: "Concatenate Arrays." - examples: { '(concat arr1 arr2 [arr3…])' } - - value: class extends PureOp - pattern: any\rep 2 - type: (inputs) => - size = 0 - type = inputs[1]\type!.type - - for input in *inputs - array = input\type! - - if array.type ~= type - msg = string.format "Cannot concatenate different arrays %s, %s", - inputs[1]\type!, array - error Error 'argument', msg - - size += array.size - - Array size, type - - tick: => - arrays = @unwrap_all! - out = {} - - for array in *arrays - for val in *array - table.insert out, val - - @out\set out - -array_constr = builtins!\get('array').result -map = Constant.meta - meta: - name: 'map' - summary: "Apply an function to each value in an array." - examples: { '(map array fn)' } - description: " -Invokes `fn` once for each element in `array` and returns an array of the results. -`fn` must take one argument and return the same type consistently." - - value: class extends Builtin - eval: (scope, tail) => - L\trace "evaling #{@}" - assert #tail == 2, "'map' takes exactly two arguments" - tail = [L\push t\eval, scope for t in *tail] - { array, fn } = tail - - fndef = fn.result - assert fn\type! == T.fndef, "fn has to be a fndef" - array_type = array\type! - assert array_type.__class == Array, Error 'argument', "expected an Array" - - invocations = for i=1, array_type.size - tag_o = @tag\clone Tag.parse tostring i - tag_i = @tag\clone tag_o - Cell tag_o, { - with Constant.literal T.fndef, fndef!, 'fn' - .meta = fndef.meta - Cell tag_i, { - Constant.literal T.opdef, get!, 'get' - Constant.literal array_type, array.result!, 'array' - Constant.num i-1 - } - } - - tag = @tag\clone Tag.parse '-1' - inner = Cell tag, { - Constant.literal T.opdef, array_constr, 'array' - unpack invocations - } - super inner\eval scope - - -Constant.meta - meta: - name: 'array' - summary: "Utilities for dealing with arrays." - - value: - :get, :set - :head, :tail, :prepend - :insert, :remove - :map - - :size, :concat diff --git a/alv-lib/struct-.moon b/alv-lib/struct-.moon new file mode 100644 index 0000000..94bd82f --- /dev/null +++ b/alv-lib/struct-.moon @@ -0,0 +1,129 @@ +import Struct, Op, PureOp, Constant, Error, const, sig, evt from require 'alv.base' + +any = sig! / evt! +key_type = const.str / const.sym + +get = Constant.meta + meta: + name: 'get' + summary: "Index into a struct." + examples: { '(get struct key)' } + description: "Get the value at `key`. + +`key` has to be a constant expression." + + value: class extends PureOp + pattern: any + key_type + type: (inputs) => + { struct, key } = inputs + struct\type!\get key.result! + + tick: => + { struct, key } = @unwrap_all! + @out\set struct[key] + +set = Constant.meta + meta: + name: 'set' + summary: "Update values in a struct." + examples: { '(set struct key val)' } + description: "Set the value for `key` to `val`. + +`key` has to be a constant expression. This is a pure op, so at most one of +`struct` and `val` may be a !-stream." + + value: class extends PureOp + pattern: any + key_type + any + type: (inputs) => + { struct, key, val } = inputs + type = struct\type! + expected = type\get key.result! + + if expected ~= val\type! + msg = string.format "expected value for key '%s' to be %s, not %s", + key.result!, expected, val\type! + error Error 'argument', msg + + type + + tick: => + { struct, key, val } = @unwrap_all! + + struct = {k,v for k,v in pairs struct} + struct[key] = val + + @out\set struct + +insert = Constant.meta + meta: + name: 'insert' + summary: "Insert a new value into a struct." + examples: { '(insert struct key val)' } + description: "Insert `val` into `struct` at `key`. + +`key` has to be a constant expression. This is a pure op, so at most one of +`struct` and `val` may be a !-stream." + + value: class extends PureOp + pattern: any + key_type + any + type: (inputs) => + { struct, key, val } = inputs + type = struct\type! + key = key.result! + + if type.types[key] + msg = string.format "key '%s' already exists in value of type %s", + key, type + error Error 'argument', msg + + types = {k,v for k,v in pairs type.types} + types[key] = val\type! + Struct types + + tick: => + { struct, key, val } = @unwrap_all! + + struct = {k,v for k,v in pairs struct} + struct[key] = val + + @out\set struct + +remove = Constant.meta + meta: + name: 'remove' + summary: "Remove values from a struct." + examples: { '(remove struct key)' } + description: "Removes the value at index `key` from `struct`. + +`key` has to be a constant expression." + + value: class extends PureOp + pattern: any + key_type + type: (inputs) => + { struct, key } = inputs + type = struct\type! + key = key.result! + + -- check key exists + type\get key + + types = {k,v for k,v in pairs type.types} + types[key] = nil + Struct types + + tick: => + { struct, key, val } = @unwrap_all! + + struct = {k,v for k,v in pairs struct} + struct[key] = nil + + @out\set struct + +Constant.meta + meta: + name: 'struct' + summary: "Utilities for dealing with structs." + + value: + :get, :set + :insert, :remove diff --git a/alv-lib/struct.moon b/alv-lib/struct.moon deleted file mode 100644 index 94bd82f..0000000 --- a/alv-lib/struct.moon +++ /dev/null @@ -1,129 +0,0 @@ -import Struct, Op, PureOp, Constant, Error, const, sig, evt from require 'alv.base' - -any = sig! / evt! -key_type = const.str / const.sym - -get = Constant.meta - meta: - name: 'get' - summary: "Index into a struct." - examples: { '(get struct key)' } - description: "Get the value at `key`. - -`key` has to be a constant expression." - - value: class extends PureOp - pattern: any + key_type - type: (inputs) => - { struct, key } = inputs - struct\type!\get key.result! - - tick: => - { struct, key } = @unwrap_all! - @out\set struct[key] - -set = Constant.meta - meta: - name: 'set' - summary: "Update values in a struct." - examples: { '(set struct key val)' } - description: "Set the value for `key` to `val`. - -`key` has to be a constant expression. This is a pure op, so at most one of -`struct` and `val` may be a !-stream." - - value: class extends PureOp - pattern: any + key_type + any - type: (inputs) => - { struct, key, val } = inputs - type = struct\type! - expected = type\get key.result! - - if expected ~= val\type! - msg = string.format "expected value for key '%s' to be %s, not %s", - key.result!, expected, val\type! - error Error 'argument', msg - - type - - tick: => - { struct, key, val } = @unwrap_all! - - struct = {k,v for k,v in pairs struct} - struct[key] = val - - @out\set struct - -insert = Constant.meta - meta: - name: 'insert' - summary: "Insert a new value into a struct." - examples: { '(insert struct key val)' } - description: "Insert `val` into `struct` at `key`. - -`key` has to be a constant expression. This is a pure op, so at most one of -`struct` and `val` may be a !-stream." - - value: class extends PureOp - pattern: any + key_type + any - type: (inputs) => - { struct, key, val } = inputs - type = struct\type! - key = key.result! - - if type.types[key] - msg = string.format "key '%s' already exists in value of type %s", - key, type - error Error 'argument', msg - - types = {k,v for k,v in pairs type.types} - types[key] = val\type! - Struct types - - tick: => - { struct, key, val } = @unwrap_all! - - struct = {k,v for k,v in pairs struct} - struct[key] = val - - @out\set struct - -remove = Constant.meta - meta: - name: 'remove' - summary: "Remove values from a struct." - examples: { '(remove struct key)' } - description: "Removes the value at index `key` from `struct`. - -`key` has to be a constant expression." - - value: class extends PureOp - pattern: any + key_type - type: (inputs) => - { struct, key } = inputs - type = struct\type! - key = key.result! - - -- check key exists - type\get key - - types = {k,v for k,v in pairs type.types} - types[key] = nil - Struct types - - tick: => - { struct, key, val } = @unwrap_all! - - struct = {k,v for k,v in pairs struct} - struct[key] = nil - - @out\set struct - -Constant.meta - meta: - name: 'struct' - summary: "Utilities for dealing with structs." - - value: - :get, :set - :insert, :remove diff --git a/spec/lang/array_spec.moon b/spec/lang/array_spec.moon index fc7ce43..f1fe0ab 100644 --- a/spec/lang/array_spec.moon +++ b/spec/lang/array_spec.moon @@ -2,7 +2,7 @@ import TestPilot from require 'spec.test_setup' import T, Array, Constant from require 'alv' describe "array", -> - test = TestPilot '', '(import* array)\n' + test = TestPilot '', '(import* array-)\n' svec3 = Array 3, T.str diff --git a/spec/lang/struct_spec.moon b/spec/lang/struct_spec.moon index d0af6bc..6a6e0fa 100644 --- a/spec/lang/struct_spec.moon +++ b/spec/lang/struct_spec.moon @@ -2,7 +2,7 @@ import TestPilot from require 'spec.test_setup' import T, Struct, Constant from require 'alv' describe "struct", -> - test = TestPilot '', '(import* struct)\n' + test = TestPilot '', '(import* struct-)\n' ab = Struct { a: T.num, b: T.bool } -- cgit v1.2.3