diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2020-05-08 12:13:34 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2020-05-08 12:13:34 +0000 |
| commit | 680eff29dc11cd702b194d2bd50256069144f586 (patch) | |
| tree | 43e75de431a30e1244576ec4e0cdcf4a2bbbc311 | |
| parent | rename RTNode.value to RTNode.result (to match Result class) (diff) | |
| download | alive-680eff29dc11cd702b194d2bd50256069144f586.tar.gz alive-680eff29dc11cd702b194d2bd50256069144f586.zip | |
add shorthands for builtin primitives to Primitive
| -rw-r--r-- | alv/builtin.moon | 2 | ||||
| -rw-r--r-- | alv/cell.moon | 6 | ||||
| -rw-r--r-- | alv/invoke.moon | 10 | ||||
| -rw-r--r-- | alv/result/const.moon | 32 | ||||
| -rw-r--r-- | alv/scope.moon | 2 | ||||
| -rw-r--r-- | alv/type.moon | 95 | ||||
| -rw-r--r-- | spec/result/const_spec.moon | 36 |
7 files changed, 125 insertions, 58 deletions
diff --git a/alv/builtin.moon b/alv/builtin.moon index 740da25..29602e2 100644 --- a/alv/builtin.moon +++ b/alv/builtin.moon @@ -313,7 +313,7 @@ trace = Constant.meta tag = @tag\clone Tag.parse '-1' inner = Cell tag, { - Constant.literal (Primitive 'opdef'), traceOp, 'trace' + Constant.literal Primitive.op, traceOp, 'trace' Constant.str tostring tail[1] tail[1] } diff --git a/alv/cell.moon b/alv/cell.moon index a61f8de..759e7aa 100644 --- a/alv/cell.moon +++ b/alv/cell.moon @@ -74,11 +74,11 @@ class Cell head = assert @head!, Error 'syntax', "cannot evaluate empty expr" head = (head\eval scope)\const! Builtin = switch head.type - when (Primitive 'opdef') + when Primitive.op op_invoke - when (Primitive 'fndef') + when Primitive.fn fn_invoke - when (Primitive 'builtin') + when Primitive.builtin head\unwrap! else error Error 'type', "#{head} is not an opdef, fndef or builtin" diff --git a/alv/invoke.moon b/alv/invoke.moon index 0629b59..390e19f 100644 --- a/alv/invoke.moon +++ b/alv/invoke.moon @@ -8,10 +8,6 @@ import Scope from require 'alv.scope' import Primitive from require 'alv.type' import Error from require 'alv.error' -opdef = Primitive 'opdef' -fndef = Primitive 'fndef' -sym = Primitive 'sym' - get_name = (value, raw) -> meta = if value.meta then value.meta.name locl = if raw and raw.type == 'sym' then raw! @@ -39,7 +35,7 @@ class op_invoke extends Builtin @op = prev.op\fork! prev.forked = COPILOT.T else - def = @head\unwrap opdef, "cant op-invoke #{@head}" + def = @head\unwrap Primitive.opdef, "cant op-invoke #{@head}" @op = def! --- `Builtin:destroy` implementation. @@ -108,7 +104,7 @@ class fn_invoke extends Builtin name = get_name @head, @cell\head! frame = "invoking function #{name} at [#{@tag}]" - fndef = @head\unwrap fndef, "cant fn-invoke #{@head}" + fndef = @head\unwrap Primitive.fndef, "cant fn-invoke #{@head}" { :params, :body } = fndef if #params != #tail err = Error 'argument', "expected #{#params} arguments, found #{#tail}" @@ -118,7 +114,7 @@ class fn_invoke extends Builtin fn_scope = Scope fndef.scope, caller_scope children = for i=1,#params - name = params[i]\unwrap sym + name = params[i]\unwrap Primitive.sym with L\push tail[i]\eval, caller_scope fn_scope\set name, \make_ref! diff --git a/alv/result/const.moon b/alv/result/const.moon index 615e426..b88de2c 100644 --- a/alv/result/const.moon +++ b/alv/result/const.moon @@ -128,52 +128,52 @@ class Constant extends Result -- @treturn Constant @wrap: (val, name='(unknown)') -> typ = switch type val - when 'number' then 'num' - when 'string' then 'str' + when 'number' then Primitive.num + when 'string' then Primitive.str when 'table' if rawget val, '__base' -- a class switch ancestor val - when base.Op then 'opdef' - when base.Builtin then 'builtin' + when base.Op then Primitive.op + when base.Builtin then Primitive.builtin else error "#{name}: cannot wrap class '#{val.__name}'" elseif val.__class -- an instance switch ancestor val.__class - when scope.Scope then 'scope' - when base.FnDef then 'fndef' + when scope.Scope then Primitive.scope + when base.FnDef then Primitive.fn when Result then return val else error "#{name}: cannot wrap '#{val.__class.__name}' instance" else -- plain table val = scope.Scope.from_table val - 'scope' + Primitive.scope else error "#{name}: cannot wrap Lua type '#{type val}'" - Constant (Primitive typ), val + Constant typ, val --- create a constant number. - -- @tparam number val the number + -- @tparam number num the number -- @treturn Constant - @num: (val) -> Constant num, val, tostring val + @num: (num) -> Constant Primitive.num, num, tostring num --- create a constant string. - -- @tparam string val the string + -- @tparam string str the string -- @treturn Constant - @str: (val) -> Constant str, val, "'#{val}'" + @str: (str) -> Constant Primitive.str, str, "'#{str}'" --- create a constant symbol. - -- @tparam string val the symbol + -- @tparam string sym the symbol -- @treturn Constant - @sym: (val) -> Constant sym, val, val + @sym: (sym) -> Constant Primitive.sym, sym, sym --- create a constant boolean. - -- @tparam boolean val the boolean + -- @tparam boolean bool the boolean -- @treturn Constant - @bool: (val) -> Constant bool, val, tostring val + @bool: (bool) -> Constant Primitive.bool, bool, tostring bool --- create a forced-literal Constant. -- diff --git a/alv/scope.moon b/alv/scope.moon index 462d7a6..b150280 100644 --- a/alv/scope.moon +++ b/alv/scope.moon @@ -57,7 +57,7 @@ class Scope child = @get start if not child error Error 'reference', "undefined symbol '#{start}'" - if child\type! != (Primitive 'scope') + if child\type! != Primitive.scope error Error 'reference', "'#{start}' is not a scope" child.result!\get rest, while_msg diff --git a/alv/type.moon b/alv/type.moon index 629ac50..779cbe5 100644 --- a/alv/type.moon +++ b/alv/type.moon @@ -20,24 +20,74 @@ same = (a, b) -> true -class Primitive - new: (@type) => +--- Interface for types. +-- @type Type +class Type + new: => + + --- pretty-print a value of this type. + -- @function pp + -- @tparam any value + -- @treturn string +--- Primitive type. +-- +-- Implements the `Type` interface. +-- +-- @type Primitive +class Primitive pp: (value) => tostring value __eq: (other) => @type == other.type __tostring: => @type -class Struct - new: (@types) => + --- shorthand for number type. + -- @tfield Primitive num + @num: @ 'num' - --- create a new struct with a selection of keys - project: (keys) => - types = {} - for key in *keys - types[key] = @types[key] - @@ types + --- shorthand for string type. + -- @tfield Primitive str + @str: @ 'str' + + --- shorthand for symbol type. + -- @tfield Primitive sym + @sym: @ 'sym' + + --- shorthand for boolean type. + -- @tfield Primitive bool + @bool: @ 'bool' + + --- shorthand for bang type. + -- @tfield Primitive bang + @bang: @ 'bang' + + --- shorthand for `Scope` type. + -- @tfield Primitive scope + @scope: @ 'scope' + + --- shorthand for `Op` type. + -- @tfield Primitive op + @op: @ 'opdef' + + --- shorthand for `FnDef` type. + -- @tfield Primitive fn + @fn: @ 'fndef' + + --- shorthand for `Builtin` type. + -- @tfield Primitive builtin + @builtin: @ 'builtin' + --- instantiate a Primitive type. + -- @classmethod + -- @tparam string type the typename + new: (@type) => + +--- Struct/Hashmap type. +-- +-- Implements the `Type` interface. +-- +-- @type Struct +class Struct pp: (value) => inner = table.concat ["#{k}: #{@types[k]\pp v}" for k, v in opairs value], ', ' "{#{inner}}" @@ -47,9 +97,24 @@ class Struct inner = table.concat ["#{k}: #{v}" for k, v in opairs @types], ', ' "{#{inner}}" -class Array - new: (@size, @type) => + --- create a new struct type with a subset of keys. + project: (keys) => + types = {} + for key in *keys + types[key] = @types[key] + @@ types + --- instantiate a Primitive type. + -- @classmethod + -- @tparam {string=Type} types + new: (@types) => + +--- Array type. +-- +-- Implements the `Type` interface. +-- +-- @type Array +class Array pp: (value) => inner = table.concat [@type\pp v for v in *value], ' ' "[#{inner}]" @@ -57,6 +122,12 @@ class Array __eq: (other) => @size == other.size and @type == other.type __tostring: => "#{@type}[#{@size}]" + --- instantiate an Array type. + -- @classmethod + -- @tparam number size + -- @tparam Type type + new: (@size, @type) => + { :Primitive :Array diff --git a/spec/result/const_spec.moon b/spec/result/const_spec.moon index 31eec4e..dfcdafa 100644 --- a/spec/result/const_spec.moon +++ b/spec/result/const_spec.moon @@ -14,12 +14,12 @@ describe 'Constant', -> describe '.wrap', -> it 'wraps numbers', -> got = Constant.wrap 3 - assert.is.equal (Primitive 'num'), got.type + assert.is.equal Primitive.num, got.type assert.is.equal 3, got.value it 'wraps strings', -> got = Constant.wrap "im a happy string" - assert.is.equal (Primitive 'str'), got.type + assert.is.equal Primitive.str, got.type assert.is.equal "im a happy string", got.value it 'wraps Constants', -> @@ -31,27 +31,27 @@ describe 'Constant', -> it 'wraps Opdefs', -> got = Constant.wrap TestOp - assert.is.equal (Primitive 'opdef'), got.type + assert.is.equal Primitive.op, got.type assert.is.equal TestOp, got.value it 'wraps Bultins', -> got = Constant.wrap TestBuiltin - assert.is.equal (Primitive 'builtin'), got.type + assert.is.equal Primitive.builtin, got.type assert.is.equal TestBuiltin, got.value it 'wraps Scopes', -> sub = Scope! got = Constant.wrap sub - assert.is.equal (Primitive 'scope'), got.type + assert.is.equal Primitive.scope, got.type assert.is.equal sub, got.value it 'wraps tables', -> pi = Constant.num 3.14 got = Constant.wrap { :pi } - assert.is.equal (Primitive 'scope'), got.type + assert.is.equal Primitive.scope, got.type assert.is.equal pi, (got.value\get 'pi')\const! describe ':unwrap', -> @@ -61,23 +61,23 @@ describe 'Constant', -> assert.is.equal 'hi', (Constant.sym 'hi')\unwrap! test 'can assert the type', -> - assert.is.equal 3.14, (Constant.num 3.14)\unwrap Primitive 'num' - assert.is.equal 'hi', (Constant.str 'hi')\unwrap Primitive 'str' - assert.is.equal 'hi', (Constant.sym 'hi')\unwrap Primitive 'sym' - assert.has_error -> (Constant.num 3.14)\unwrap Primitive 'sym' - assert.has_error -> (Constant.str 'hi')\unwrap Primitive 'num' - assert.has_error -> (Constant.sym 'hi')\unwrap Primitive 'str' + assert.is.equal 3.14, (Constant.num 3.14)\unwrap Primitive.num + assert.is.equal 'hi', (Constant.str 'hi')\unwrap Primitive.str + assert.is.equal 'hi', (Constant.sym 'hi')\unwrap Primitive.sym + assert.has_error -> (Constant.num 3.14)\unwrap Primitive.sym + assert.has_error -> (Constant.str 'hi')\unwrap Primitive.num + assert.has_error -> (Constant.sym 'hi')\unwrap Primitive.str test 'has __call shorthand', -> assert.is.equal 3.14, (Constant.num 3.14)! assert.is.equal 'hi', (Constant.str 'hi')! assert.is.equal 'hi', (Constant.sym 'hi')! - assert.is.equal 3.14, (Constant.num 3.14) Primitive 'num' - assert.is.equal 'hi', (Constant.str 'hi') Primitive 'str' - assert.is.equal 'hi', (Constant.sym 'hi') Primitive 'sym' - assert.has_error -> (Constant.num 3.14) Primitive 'sym' - assert.has_error -> (Constant.str 'hi') Primitive 'num' - assert.has_error -> (Constant.sym 'hi') Primitive 'str' + assert.is.equal 3.14, (Constant.num 3.14) Primitive.num + assert.is.equal 'hi', (Constant.str 'hi') Primitive.str + assert.is.equal 'hi', (Constant.sym 'hi') Primitive.sym + assert.has_error -> (Constant.num 3.14) Primitive.sym + assert.has_error -> (Constant.str 'hi') Primitive.num + assert.has_error -> (Constant.sym 'hi') Primitive.str describe 'overrides __eq', -> it 'compares the type', -> |
