aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-05-08 12:13:34 +0000
committers-ol <s-ol@users.noreply.github.com>2020-05-08 12:13:34 +0000
commit680eff29dc11cd702b194d2bd50256069144f586 (patch)
tree43e75de431a30e1244576ec4e0cdcf4a2bbbc311
parentrename RTNode.value to RTNode.result (to match Result class) (diff)
downloadalive-680eff29dc11cd702b194d2bd50256069144f586.tar.gz
alive-680eff29dc11cd702b194d2bd50256069144f586.zip
add shorthands for builtin primitives to Primitive
-rw-r--r--alv/builtin.moon2
-rw-r--r--alv/cell.moon6
-rw-r--r--alv/invoke.moon10
-rw-r--r--alv/result/const.moon32
-rw-r--r--alv/scope.moon2
-rw-r--r--alv/type.moon95
-rw-r--r--spec/result/const_spec.moon36
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', ->