51 KiB
This is the reference manual for all Loom objects and methods (i.e. the "library"). It is not the language reference, but since Loom is mostly library, this holds the bulk of the documentation.
It is generated via (extremely hacky) script from the Loom sources and comments therein.
Loom Class Heirarchy
Well-known Objects
class AbstractDict < Object
Abstract base class for dictionaries.
Subclasses will need to define size
, at
and
each_value_and_key
.
Enumerable
is a delegate, so each
and friends work. Keys take
the role of index in this case.
Inner methods
-
_copy |deep|
(internal, undocumented)
-
== |other|
Dictionaries are equal if both are subinstances of AbstractDict and corresponding key and value pairs are equal according to
==
. -
at
(abstract) -
copy
Return a copy of
self
of the same class with the same keys and values (but not Pairs). -
deepCopy
Return a copy of
self
of the same class with deep copies of the keys and values. -
each_value_and_key
(abstract) -
fetchOr
(abstract) -
has_key
(abstract) -
keys
Return a Vector containing all of the keys.
-
size
(abstract) -
str
Produce a human-friendly printable string
-
values
Return a Vector containing all of the values.
class AddonTrait < Trait
AddonTrait
s are bundles of methods that can be added to new
classes. They are basically mix-ins.
An AddonTrait
can contain methods just like a class but cannot be
instantiated. Instead, it must be added to a class as an inner
delegate. Methods do not have access to the class's slots. Instead,
they must send messages to self
.
Outer methods
-
new |*delegates|
Create a new AddonTrait; zero or more arguments are delegates.
Inner methods
-
new
Fails; instances cannot be instantiated.
-
subclass |slots, *delegates|
Convenience method; common interface with Class. Equivalent to
AddonTrait.new(self)
.
class Block < Method
Blocks are unnamed functions defined inside method or block
invocations (i.e. Lambdas). While it is possible to create a
Block
(by way of creating an intermediate ProtoMethod
first),
you will usually want to just use the { ... }
syntax instead.
See the language reference for more details.
Block cannot be subclassed.
Outer methods
-
new
Fails with an error; should not be called.
Inner methods
-
assert |*msgparts|
Evaluate self and fail with a message if it returns false. Message is the arguments joined with a space separator.
-
assertmsg |*msgparts|
Beginnings of a test framework. Like Block::assert but always prints the message and prints FAILED! on failure.
-
benchmark |action|
-
call |*args|
Invoke this Block with arguments and return the result.
-
callAndEnsure |ensure_block|
Evaluate
self
, thenensure_block
. Returns the result ofself
if it is allowed to complete (i.e. doesn't exit via exception or return).ensure_block
is guaranteed to always run, regardless of howself
is exited. -
catch |exception_class, handler_block|
Evaluate
self
and return its result.If doing so causes an exception to be thrown (with
Context::throw
) and the object's class isexception_class
or one of its subclasses, evaluateshandler_block
(which must be a Block) with the exception object as its parameter and returns the result of that block instead. -
catchAndEnsure |klass, handler, ensure_block|
Like
catch
except that theensure_block
will always be evaluated. Specifically, it:-
Evaluates
self
. If no exception is thrown, the result is returned, as withcall()
. -
If an exception was raised that is an instance of
klass
, it then evaluateshandler
with the exception as its argument and (if there isn't another exception) returns its result. -
Evaluates
ensure_block
with no arguments and discards the result. This will always happen, regardless of how the the blocks exited.
-
-
copy
Blocks aren't copyable so this returns
self
-
deepCopy
Blocks aren't copyable so this returns
self
-
str
Return a human-friendly String describing
self
. -
while |body|
Repeatedly evaluates self, which must return true or false. Each time it returns true, it then evaluates the
body
, also a block.Returns the result of the last call to
body
or nil if it was never called. -
whileFalse
Evaluates
self
until it returnsTrue
instead ofFalse
. -
whileTrue
Evaluates
self
until it returnsFalse
instead ofTrue
. Any other result is an error.Equivalent to
Block::while
called with an empty block argument.
class Boolean < Object
Class of the two Boolean values (True
and False
, also spelled
true
and false
).
Most methods are actually implemented as outer methods by each of the instances in order to provide behaviour specific to their truth value.
For example, the method if
(evaluate block if true) has an
implementation in both True
and False
; True
's implementation
always evaluates the block and False
's never does. An expression
like
a > b .if { do_thing(a,b) }
does the expected thing because the conditional's response contains
the expected if
implementation.
Is is not possible to instantiate or subclass Boolean
.
Inner methods
-
&& |body|
Short-circuited boolean and.
If
self === True
, evaluates blockbody
and returns its result; otherwise, returnsself
. -
|| |body|
Short-circuited boolean or.
If
self === False
, evaluates blockbody
and returns its result; otherwise, returnsself
. -
clone
Booleans are unique and so can't be cloned; just returns
self
. -
ifElse |true_body, false_body|
Evaluate
true_body
ifself === True
;false_body
otherwise. Returns the result of the evaluated block. -
ifNot |body|
Evaluate
body
ifself === False
. -
str
class Class < Trait
The metaclass; all classes are instances of class Class
. This
includes Class
itself.
Class
provides the outer interface for basic class behaviour,
specifically instance creation (i.e. factory methods) subclass
creation, and the ability to access the new class's inner method
dictionary.
Inner methods
-
<= |klass|
Test if RHS is self or a subclass of it.
-
< |klass|
Test if RHS is a subclass of
self
-
>= |klass|
Test if RHS is
self
or one of its superclasses. -
> |klass|
Test if RHS is a superclass of
self
. -
abstract_method |name|
Define a method with the given name. Calling it will throw a fatal error.
-
abstract_subclass |*args|
Define an abstract subclass. Just like
subclass
except thatinitialize
will throw a fatal error. -
accessible |slotname|
Equivalent to calling both 'readable' and 'writeable'.
-
new |*args|
Create a new instance of
self
and call itsinitialize
method with all of the argumentsnew
received. -
readable |slotname|
Add a getter to
self
whose name is given byslotname
that retrieves the contents of the slot named byslotname
. -
slots
Return a Vector containing the names of all of the slots an instance of
self
will have in a well-defined order. This includes the slots of all of the superclasses in their order before this class's slots. -
str
Return a human-friendly printable description of self. This is the annotation if set; otherwise, it will make something up.
-
subclass |slots, *delegates|
Create and return a subclass of
self
.slots
is a (possibly empty) vector of symbols that represent the names of the slots instances will have. If one or more delegates is given, they are added to the new class's list of inner delegates. Delegates must beAddonTrait
s.subclass
will create the new class'sslots
method. -
superclass
Return the superclass of self. This is always the first inner delegate. Returns null if there is none.
-
writable |slotname|
Add a setter to
self
that sets the contents of the slot named byslotname
to its argument and returns the new value. The method is named byslotname
but has an underscore ("_") appended so that the field assigment syntax will work.
addon Comparable
Can be added to classes whose instances have a well-defined order to
provide comparison with respect to that order. The delegating class
must implement method <
(i.e. less-than) as well as provide a
reasonable implementation of ==
.
Inner methods
-
<= |other|
Test if
self
is less than or equal toother
. -
< |other|
Fails if called; this should be implemented by the class.
-
>= |other|
Test if
self
is greater than or equal toother
. -
> |other|
Test if
self
is greater thanother
.
class Context < Object
Context
objects represent the local activation record (i.e. "stack
frame") of the current method or block. The hold local variables
and provide the interface for accessing variables.
Instances are created by the interpreter. It is not possible to
create or copy a Context
from Loom code or to create a subclass of
Context
.
Inner methods
-
copy
Contexts aren't copyable so this returns
self
. -
deepCopy
Contexts aren't copyable so this returns
self
. -
defglobal |name, value, *maybe_annotation|
Defines a global variable or constant.
self.defglobal(name, value [, annotation])
'name' must be a symbol and must not be defined in the global namespace. 'value' can be any value and will be assigned to it. If a third argument is given, it is expected to be the annotation. (More than 3 arguments are an error.)
Providing an annotation is equivalent to doing
value.annotation = annotation
; depending on whatvalue
is, this may be a no-op. The primary use for this is making it easy to tell classes their names. -
ensure |ensure_block|
Attach a Block to
here
that will be evaluated after this method call terminates, regardless of how that happens. The block's result is discarded. -
fail
Exit with a fatal error. Should be overridden in the syslib to throw a Failure exception.
-
get |name|
Given a symbol
name
, return the value of the variable named by that symbol. Fails if the name is undefined.Roughly equivalent to a bare variable. That is,
foo
and
Here.get(:foo)
do the same thing, with the former having the advantage of compile-time checking.
-
getglobal |name|
Given a symbol
name
, return the value of the global variable named by that symbol. Fails if the name is undefined.Unlike
get
or ordinary name lookup, this jumps directly to the global namespace, bypassing any local or instance variables that may have masked it. -
global_scope
Return the global scope associated with self; this could be self if self is the global context.
-
has |name|
Test if there is a variable visible in the current scope (this one OR an outer scope) with the given name. Returns true if there is, false otherwise.
-
hasglobal |name|
Test if there is a global variable with the given name. Returns true if there is, false otherwise.
-
method_scope
Return the innermost context that is not a block's context. Specifically, if self belongs to a block evaluation, it searches outward until it finds the first context that does not. This will either be a method's or the global context. Otherwise, it returns self.
-
names
Return a Vector containing all of the names defined locally in this context. (I.e. it does not include visible names defined in outer scopes.)
-
outer
Return the next outer scope or nil if this is the global context.
-
return |result|
Causes the context to return. That is, the function stops being evaluated and the
result
is given to the caller.If
self
is the global context, this will fail. -
set |name, value|
Given a symbol
name
and value, store the value at the variable named by thename
according to the standard scope resolution rules. Fails if the name is undefined or unwritable. -
str
-
super_send |message, *args|
Equivalent to
super_sendv
(i.e. sendsmessage
with the search starting in the calling method's owner's delegates) but takes a variadic argument list. -
super_sendv |message, args|
Send message
message
toself
withargs
as the list of parameters, but start the method search at the delegate list of the object which owns the method that's doing the send.This lets us invoke a superclass's method that has been overridden in the current class.
-
throw |obj|
Throw an exception.
obj
may be any object that is an instance of Object or one of its subclasses; 'catch' statements will catch this if the the thrown object is an instance or subinstance of the class it's waiting for.
addon Enumerable
This is an addon which provides methods for applying a block to every element in a sufficiently vector-like object.
Classes delegating to Enumerable must implement size
, and at
as
expected. Classes that do not behave like a zero-based array must
also implement each_value_and_key
.
Inner methods
-
contains |value|
Test if an element equal to
value
is present. -
each |block|
Call 'block' on each element in increasing order.
-
each_idx |block|
Convenient wrapper around
each_value_and_key
. -
each_value_and_key |block|
Call 'block' on each element in increasing order with the element and its index as arguments.
This will work for any collection whose keys are a continuous range of integers between 0 and one less than the number of items (i.e. like a Vector). Collection classes that do not follow this protocol need to provide their own
each_value_and_key
which must evaluate the block for each key and corresponding value in the collection exactly once.(Warning: future directions may add additional constraints on this including ordering.)
-
has_all |block|
Test if
block
returns true for all items in self -
has_any |block|
Call 'block' on some or all elements in
self
and return true ifblock
returns true for at least one element. -
has_none |block|
Test if
block
returns false for all items in self -
inject |initial, block|
Combines all elements of self by applying a two-argument block where the second argument is the current element and the first the result of the previous block or 'initial' if it is the first call.
-
map |block|
Call 'block' on each element in increasing order and return a vector containing the results of each block call.
-
reduce |block|
Combines all but the first elements of self by applying a two-argument block where the first argument is the result of the previous block evaluation and the second is the current item. The first element is used as the initial value.
This is like
inject
except that the first element is used as the initial value. -
reject |block|
Like 'select' but returns only those items for which the block returns false.
-
select |block|
Classic reduce. Return a Vector of those items for which the block returns true.
class Exception < Object
Base class for all Exceptions. Exception objects should be subinstances of this class unless there's a very good reason not to.
Inner methods
-
initialize |txt|
-
str
-
text
Base class for all Exceptions. Exception objects should be subinstances of this class unless there's a very good reason not to.
class Failure < Exception
Concrete base class for exceptions originating in software errors. Throwing one of these indicates that the program's state is invalid; these should only be caught as part of exiting gracefully.
object False = Boolean.new
The False boolean value. (Also spelled false
).
Outer methods
-
& |other|
Perform a boolean and operation; return True if
self
andother
are both True and False otherwise. Bothself
andother
must be booleans. -
| |other|
Perform a boolean or operation; return True if
self
and/orother
is True and False if it isn't. Bothself
andother
must be booleans. -
if |body|
Evaluate
body
ifself === True
and don't ifself === False
.Returns the
body
's value if it's evaluated. -
not
Return the logical inverse of
self
.
class File < Object
Basic file access objects. Handles reading and writing of strings. Binary data is also read into or written from strings; sorry about that.
Outer methods
-
on |path, mode_str, block|
Opens a file according to
path
andmode_str
(seeFile::initialize
), then evaluatesblock
with the File instance as its argument, closes the handle, and returns the block's result. It is safe to exit the block viareturn
or an exception; the handle will still be closed.
Inner methods
-
_check |write_mode|
(internal, undocumented)
-
close
Close this file handle.
-
copy
File objects are not copyable so this returns
self
. -
eof
Test if the file handle is open for reading and at end-of-file
-
initialize |path, mode_str|
Opens this File onto the file at
path
.mode_str
is expected to be a C-style open mode string (one of "r" or "w" with an optional "b" appended.) -
is_ok
Test if self is not in an error state. Note that end-of-file is not considered an error.
-
is_open
Test if self is open.
-
readbytes |count|
Read 'count' bytes from the stream and return them in a string. If count exceeds the remaining bytes in the file, return what's left. If already at EOF, returns an empty string.
-
readline
Read a newline-delimited line and return it, minus the newline character. If EOF is reached before the next delimiter, all characters are returned. If already at EOF, returns an empty string.
-
str
Return a printable description.
-
writebytes |bytes|
Write a string to the file unmodified.
-
writeline |line|
Write a string to the file and append a newline.
class IntFH < Object
Internal file handle. This provides code and data used for
interfacing with the underlying IO routines (currently C++
std::iostream
, but no promises).
This is an internal implementation detail of class File
. You
should never need to touch one of these.
object Lobby = Object.new
The object in which all toplevel expressions are evaluated.
A toplevel expression is a Loom expression that has been read from a Loom source file or entered via the REPL. It is wrapped in a method which is then invoked. This method is an outer method of Lobby.
Lobby is an instance of Object but has several slots:
Argv
holds the command-line arguments the interpreter was invoked with.LobbyFlag
is True and deprecated._last
holds the last expression evaluated on the REPL.
There are also several methods.
Outer methods
-
_check_tl |expr|
(internal, undocumented)
-
_eval_toplevel_expr
Given a Loom expression, evaluate it in the toplevel context. (This is not quite consistent with the rest of the system.)
It is aliased to
eval_toplevel_expr
, which is called by the REPL and file load interface. -
_eval_toplevel_expr_with_name_checks |expr|
(internal, undocumented)
-
_time_now
Return the time in microseconds since some point in the past. This is here for benchmarking only.
-
config |var, yes|
System configuration settings:
full_namecheck - Do a thorough check for undeclared names. If false, skips some of the slower cases.
namecheck_fatal - Treat missing names in nested blocks as fatal errors. If false, they're warnings.
optimize - Optimize method definitions. Experimental; off by default.
-
import |path|
Read in source code in the file at
path
and evaluate it within the context of the lobby. -
stack_max
Return the maximum call depth.
-
stack_max_ |max_depth|
Set the maximum call depth. This is helpful in exiting gracefully when your code contains an infinite recursion.
max_depth
must be a positive integer. Setting it too low is a very bad idea. -
str
class Method < Object
Contains the executable code of Loom object method in whatever
format the interpreter prefers. Primitive methods (i.e. part of the
interpreter) are also instances of Method
.
There is not much you can do with this class by itself; it's all done in existing libraries or syntax expansion.
Instances are normally created via ProtoMethod.make_method
;
creating one with new
may or may not work and probably won't be
useful.
Method cannot be subclassed.
Outer methods
-
new |arg_names, restvar, locals, body|
Create an instance of Method.
Don't use this. It's only here to help the older tests.
Inner methods
-
copy
Methods aren't copyable so this returns
self
-
deepCopy
Methods aren't copyable so this returns
self
-
str
class MsgExpr < Object
Instances represent Loom message-send expressions inside the Loom interpreter. Each contains three values: the receiver, the message and the argument list.
-
receiver
is the Loom expression whose value will receive the message. -
message
is a Symbol representing the nameof the message to send. -
args
is a (possibly empty) Vector of objects; their results once evaluated will be the arguments included with the message.
MsgExpr
is an ordinary slotted class.
Outer methods
slots
Inner methods
-
_fold_vector_dot_with
(internal, undocumented)
-
_is_protomethod_new
(internal, undocumented)
-
_is_rudimentarily_foldable |fold_msg|
(internal, undocumented)
-
_is_safe_to_eval |fold_msg|
(internal, undocumented)
-
_is_simple_arithmetic
(internal, undocumented)
-
_is_vector_dot_with
(internal, undocumented)
-
_most_folded_backend |fold_msg|
(internal, undocumented)
-
== |other|
MsgExpr objects are equal if the receiver, message and argument lists are also equal. This doesn't necessarily mean that their evaluated results will be equal, but that's Turing Completeness for ya.
-
args
-
deepCopy
Create a copy of self with deep copies of receiver and argument list
-
each_leaf |block|
Traverse self and all referenced MsgExpr objects and for each leaf node (i.e. receiver or parameter that is not a MsgExpr), call
block
with it as argument.Each block gets called with the leaf and the outer MsgExpr as arguments.
-
initialize |receiver, message, args|
Initializer.
-
is_foldable
Can this MsgExpr be (partially) folded?
A MsgExpr is foldable if its receiver and args are foldable OR it is safe to invoke here and now and replace with the result.
-
is_trivial_eval
Is this object trivial to interpret? (I.e. does the interpeter simply evaluate it to itself?)
-
message
-
most_folded
Return self as folded as possible. (See Object::most_folded for details.)
-
most_folded_unsafe
most_folded, but it must not be possible to modify the result. The only extra case we handle here is
Vector.with(...)
, but that's important. -
receiver
-
str
object Nil = NilClass.new
The null object. (Also spelled nil
).
Outer methods
-
is_nil
Return true if self is nil.
class NilClass < Object
This is the class of the Nil
(aka nil
) object.
It can neither be instantiated or subclassed. nil
is the only
instance.
class Number < Object, Comparable
This is the class for integer and float-point numbers. It supports common arithmetic operators plus some extras.
When performing arithmetic between integer and floating-point values, the integer will be promoted to float beforehand and the result will be a float. However, operations between integers will yield integers.
It is not possible to create a subclass of Number.
Note: the underlying implementation is somewhat simpleminded and does everything in C++, so there's a chance that future releases will be different enough to break code that depends on the fine details of this implementation. Sorry; I'll try not to do that.
Inner methods
-
% |other|
Modulo
Both arguments must be integers
-
& |other|
Bitwise AND
Both arguments must be integers
-
* |other|
Multiplication (aliased to
mult
) -
+ |other|
Addition (aliased to
add
) -
- |other|
Subtraction (aliased to
sub
) -
/ |other|
Division (aliased to
div
) -
< |other|
Test if self is less than the argument. Integers and floats are considered equivalent for this purpose. Argument must be a number.
-
<< |other|
Left shift
Both arguments must be integers
-
== |other|
Test for numeric equality.
If both arguments are integers, it compares them as integers. Otherwise, both values are compared as floating point values and subject to the limitations therein.
Numbers are never equal to non-numbers.
-
>> |other|
Right shift
Both arguments must be integers
-
^ |other|
Bitwise exclusive-OR
Both arguments must be integers
-
-> |to|
Construct a
Range
with 'from' and 'to' values fromself
andto
. -
abs
Return the absolute value of
self
. -
between |lower, upper|
Test if
self
is inclusively betweenupper
andlower
. -
hex
Return as a string 0x-prefixed hex number
-
is_float
Test if the underlying number is a floating-point value. Note that
2.0
is still a float while2.0.truncate
is not. -
is_int
Return true if self is an integer; false if it's a float. Note that an integer is different from a float with no fractional part.
That is,
2
is an integer but2.0
is not;2.0.truncate
is one, however. -
max |other|
Return the larger of self and
other
. -
min |other|
return the smaller of
self
andother
. -
pack
Return an 8-byte String containing the bytes of
self
in network (i.e. big-endian) order.self
must be an integer; it is an error to pack a floating-point value. -
truncate
Compute the nearest integer not greater in magnitude than self.
-
| |other|
Bitwise OR
Both arguments must be integers
class Object
Base class for all classes.
It can be instantiated and this is useful for creating objects with only outer methods.
Inner methods
-
=== |other|
Test if
self
andother
are the same actual object in memory. Should not be overridden by subclasses.Note: the only reason you should ever use this is to implement
==
. -
_does_not_understand |message, *args|
Fails with an error message.
This message gets sent to an object if a method lookup fails.
message
is the name of the missing method and is followed by the remaining argument list.Subclasses may override this to different things.
-
_print
Debug print method. No guarantees for the future.
-
_str_layout
Debug print method. No guarantees for the future. Uses the layout-level printer.
-
!= |other|
Inequality. I.e., test if
self == other
is false. -
== |other|
Test if
self
is equal toother
, where equality is defined by the class itself. Subclasses should override this as necessary; by default, it's equivalent to===
. -
=> |value|
Construct a Pair with the LHS as key and the RHS as value.
-
add_delegate |delegate|
Add a new AddonTrait to the list of outer delegates.
-
add_method |name, method|
Add Method
method
toself
's (outer) method dictionary with namename
(a Symbol).method
must have been defined with a list of slots that exactly matches the this object's list of slots or undefined behaviour may occur. -
add_slot |name, initial_value|
Add a slot named by
name
to the end of this object's list of slots and set its initial value toinitial_value
. (This is an "outer" slot; inner lots aren't a thing.)It is an error if there is already a slot with that name or if this is not a slotted object.
-
alias_method |from, to|
Create a new (outer) method dictionary entry named
to
that references the method named byfrom
. Both methods must belong toself
and not a delegate.from
andto
are symbols. -
annotation
Retrieve self's annotation string if self's layout supports that. Otherwise, returns an empty string.
-
annotation_
Set self's annotation string if self's layout supports that. Otherwise, does nothing. The argument must be a string.
-
class
Return
self
's class (i.e. the first outer delegate). Returnsnil
if there isn't one. -
clone
Create and return a shallow copy of this object. Not all objects can be cloned and unique objects (e.g. nil) will just return themselves.
In general, you should use
copy
ordeepCopy
instead of this.clone
is allowed to have implementation-specific quirks while the other two are not. -
copy
Create a shallow copy of this object, whatever that means for this class.
copy
is mostly the same asclone
but the latter is more implementation-dependent and has wierd corner cases.copy
should (in theory) be more consistent.Note that for objects that cannot or should not be copied,
copy
will simply return the object. -
deepCopy
Create a deep copy of this object as determined by the class.
A deep copy is a copy in which (notionally) all of the objects it references are also copied.
WARNING: we currently do not correctly handle multiple references to the same object; each will be replaced with a different copy. In the case of circular references, an infinite loop is possible.
Defaults to shallow copying; subclasses should do the right thing.
Note that for objects that cannot or should not be copied,
deepCopy
will simply return the object. -
delegates
Return the list of delegates in a Vector
-
get_method |name|
Retrieve the Method object associated with symbol
name
inself
s method dictionary. Fails if not present. -
has_method |name|
Return true if
self
contains a method named bymethod
. Returns false if not, even when a delegate has it. -
id
Return a unique ID identifying this specific object.
-
initialize |*args|
Default initializer; a stub that does nothing so that new has something to call.
-
is_a |klass|
Test if
self
is an instance ofklass
or one of its subclasses. -
is_foldable
Can this object be reduced to something smaller? That is, if it's not fully foldable, can at least some of its subexpressions be fully folded?
Returns false if self is already trivially evaluable OR if it cannot be safely folded any further.
(See
Object::most_folded
for a longer explanation.) -
is_nil
Return true if self is nil.
-
is_trivial_eval
Is this object trivial to interpret? (I.e. does the interpeter simply evaluate it to itself?)
-
most_folded
Return a value (not necessarily a copy!) that is equal to this object but as folded as possible.
"Folding" here is a reference to the concept of "constant folding"; that is, evaluating expressions at compile time when it is safe to do so.
Folding an Object attempts to return the value that you would get if the interpreter evaluated it. This is often not possible (e.g. if it contains a reference to a variable or some other non-constant state or if evaluation has side effects). In this case, some of its subexpresssions may or may not be folded. We tend to err on the side of caution and only fold things if we know it won't change the meaning of evaluation.
Most Loom objects simply evaluate to themselves. Exceptions include
Quote
andMsgExpr
; these may or may not fold to something simpler.This is the beginning of the Loom optimizer;
ProtoMethod::simplified
attempts to fold its body expressions. However, this also gets used to detect the use of undeclared variables in Blocks.simplified
will expand{...}
expressions into the intermediateProtoMethod
object, which is then queried about its variable use. -
most_folded_unsafe
Like most_folded, but the caller must guarantee that the returned object is never modified.
-
outer_slots
Return a Vector containing the names of
self
's actual slots in order. -
print
Print this object on the output stream. Equivalent to
self.str.print
. -
println
Print this object on the output stream followed by a newline.
-
send |message, *args|
Sends the given message (a Symbol) to self with the remaining arguments as the message's argument list.
-
sendv |message, args|
Like send, but takes the arguments as a single array.
-
str
Return a human-friendly String describing
self
.
class Opaque < Object
An Opaque object represents a value managed by non-Loom libraries, either from the interpreter or via an FFI.
For example, the File
class internals use an Opaque
to hold the
pointers to C++ filestreams. These are only visible to the
primitive methods that interface with the C++ IO library.
You cannot do anything useful with an Opaque from inside Loom beyond passing it around, and then only in ways that the underlying primitives can use.
Inner methods
-
copy
Fails with an error.
Unlike most uncopyables whose
copy
anddeepCopy
just returnself
, we assume that any attempt to copy one of these is an error in the class that owns it. -
deepCopy
Fails with an error.
Unlike most uncopyables whose
copy
anddeepCopy
just returnself
, we assume that any attempt to copy one of these is an error in the class that owns it.
class Pair < Object
Pair
s represent an entry in a dictionary. They contain key and
value.
Inner methods
-
== |other|
Pairs are equal iff their corresponding keys and values are equal.
-
copy
Returns a new Pair with the same key and value
-
deepCopy
Returns a new Pair with deep copies of the key and value
-
initialize |newKey, newValue|
-
key
-
str
-
value
-
value_ |val|
class ProtoMethod < Object
Precursor data structure to hold the contents of a Method or Block before defining it. This is an ordinary slotted class with five fields:
- args - Vector of symbols; list of formal arguments.
- restvar - nil or the name of the variadic argument
- locals - Vector of symbol; list of non-argument local variables.
- body - Vector of Loom expressions; the method body.
- annotation - nil or a descriptive String, typically used for diagnostics.
Instances are usually created using the brace syntax but new
works
as expected and is useful for metaprogramming.
Outer methods
-
_getter |slotname|
(internal, undocumented)
-
_insta_fail |klass, text|
(internal, undocumented)
-
_setter |slotname|
(internal, undocumented)
-
slots
Inner methods
-
_check_local_lexicals
(internal, undocumented)
-
_check_names |known_names, node|
(internal, undocumented)
-
_make_method_no_opt |outernames|
(internal, undocumented)
-
_make_method_opt |outernames|
(internal, undocumented)
-
_validate_names |name_dict|
(internal, undocumented)
-
_warn_missing_name |name|
(internal, undocumented)
-
_warning_advisory |msg|
(internal, undocumented)
-
_warning_fatal |msg|
(internal, undocumented)
-
== |other|
Equality test.
ProtoMethod
objects are equal if and only if all of the fields are also equal according to==
. -
annotation
Retrieve a copy of the annotation string (or nil, if unset)
-
args
Retrieve a copy of the formal argument list
-
body
Retrieve a deep copy of the body.
-
copy
Returns a copy of
self
.Equivalent to
deepCopy
because all ProtoMethod copies are deep. -
deepCopy
Create a copy of self with deep copies of all fields.
-
initialize |argument_list, rest_symbol, local_list, body, annotation|
ProtoMethod initializer.
Args:
- argument_list - vector of symbols; list of args
- rest_symbol - nil or a symbol; name of the variadic arg if given
- local_list - vector of symbos; list of local args
- body - vector of quoted evaluatable items
- annotation - nil or a string
-
locals
Retrieve a copy of the list of local variables
-
make_block |outer_here|
Create and return a block based on
self
. Argument must be the context (i.e.Here
) in which it is defined. If it is not, the behaviour is undefined.(Internal; do not rely on this.)
-
make_method |slots|
Create and return a method based on
self
.slots
must be a list of symbols containing the owning object's slots in the SAME ORDER as the owner's. If they do not match, behaviour is undefined. -
restvar
-
simplified
Return a copy of
self
that has been simplfied viasimplify_in_place
. -
simplify_in_place
Simplify (aka optimize) this ProtoMethod, in place (i.e. this object, not a copy of this object). Currently, 'simplify' means to attempt to fold (via
most_folded
) every expression or subexpression in this object's body and to recursively simplify any ProtoMethods found.This takes advantage of the fact that
MsgExpr::most_folded
will evaluate theProtoMethod.new
expression created by the{...}
block syntax.Note: most of the time, you should use
ProtoMethod::simplified
instead. -
str
Return a printable representation of
self
. -
unknown_names |extra_names|
Return the list of names referenced by the body that are not locally defined (i.e. names that need to be present in an outer scope) and not listed in the argument, which is a vector of symbols.
(Internal; do not rely on this.)
-
validate_as_method |slots|
Search
self
for references to undeclared names.slots
is an array of symbols containing names that were declared elsewhere and so will be resolvable at runtime; this is almost always the list of slots declared by the class that will own this method.If a missing name is called,
ProtoMethod::_warning
is invoked with an error message; depending on settings, this may be a fatal error or a warning.This can also be used to check Blocks, since they will also have
Self
defined in their scopes.
class Quote < Object
A Quote is simply an object that holds a reference to one other object. Its primary purpose is to delay evaluation in a method body.
It is mostly equivalent to a slotted object with a single slot. However, the Loom interpreter (or equivalent) will evaluate a Quote instance by retrieving the wrapped value. This allows us to (e.g.) specify a symbol in a way that yields the Symbol object itself rather than looking it up as a variable.
Outer methods
-
new |value|
Create a new instance holding
value
.
Inner methods
-
== |other|
Quotes are equal if their values are equal
-
deepCopy
Copy self the wrapped object.
-
is_foldable
Can this object be reduced to something smaller? That is, if it's not fully foldable, can at least some of its subexpressions be fully folded?
Returns false if self is already trivially evaluable OR if it cannot be safely folded any further.
(See
Object::most_folded
for a longer explanation.) -
is_trivial_eval
Is this object trivial to interpret? (I.e. does the interpeter simply evaluate it to itself?)
-
most_folded
Return
self.value
ifself
can be safely folded; otherwise, just returnself
. -
str
-
value
Return the value
self
is holding.
class Range < Object
Simulates a vector of integers sufficiently well to enumerate over.
This lets you do boring loops with integer counters via
Enumerable
.
Normally, you will want to use Number::->
to create instances:
1 -> 10 .each{|n| "n = " + (n.str) .println };
or, to increment by a different amount:
1 -> 10 * 2 .each{|n| "n = " + (n.str) .println };
Inner methods
-
* |new_by|
Return a new range with the same
from
andto
values as self but with a newby
(i.e. increment) value. -
as_vector
Convert to a Vector.
-
at |index|
Array-style reader.
-
by
-
from
-
initialize |f, t, b|
Initializer.
f
andt
are the first and last values in the range and 'b' is the increment. -
size
Array-style size
-
str
-
to
class RuntimeError < Exception
Base class for exceptions meant to be caught as part of normal operation. (I.e. throwing one of these doesn't necessarily mean the program can't keep going.)
class SlowDict < AbstractDict
SlowDict - A basic O(n) dictionary.
Inner methods
-
_index_of |key|
(internal, undocumented)
-
at |key|
Return the value associated with
key
. Fails if not present. -
atPut |key, value|
Store
value
in self atkey
. -
each_value_and_key |block|
Evaluate
block
each item and corresponding key inself
. Parameters are |value, key|. -
fetchOr |key, missing_action|
Retrieve the value at
key
. If there is none, evaluate blockmissing_action
with the key as its argument and return its result instead. -
has_key |key|
Test if
key
is present. -
initialize
-
size
Return number of items
class String < Object, Enumerable, Comparable
Fundamental built-in string type. Behaves like a Vector of single-character String objects.
Cannot be subclassed.
Note: Currently, Loom only supports 8-bit characters (I.e. ASCII or possibly your preferred 8-bit extension). This is considered a shortcoming that should be fixed, but it is unclear what that will mean when accessing individual characters in a String. Will String be an array of bytes or an array of encoded characters?
Outer methods
-
concat |*strings|
Return a new String consisting of all of the arguments appended together. All of the arguments must also be strings.
-
digit
Lowest and highest encode value of various ranges of characters. (Assumes you're using an encoding where these are contiguous.)
-
lower
Lowest and highest encode value of various ranges of characters. (Assumes you're using an encoding where these are contiguous.)
-
new |size|
Create a new String of length
size
bytes. All characters are null.size
must not be negative. -
upper
Lowest and highest encode value of various ranges of characters. (Assumes you're using an encoding where these are contiguous.)
Inner methods
-
+ |other|
Return a new string containing
self
andother
appended together. -
< |other|
Test if
self
is lexically less thanother
according to the underlying string comparison routine. This is currently the C++<
string operator, but this may change. -
== |other|
Test if
self
andother
are equal. Returns true ifother
is also a String, has the same length asself
and the same values at all corresponding indexes. -
_ctype_test |range|
(internal, undocumented)
-
at |index|
Return the character at
index
as a separate, 1-character-long string.index
must be between 0 andself.size - 1
. -
atPut |index, value|
Set the character in
self
atindex
tovalue
, which must be a string with a length of 1.index
must be between 0 andself.size - 1
. -
intern
Return a Symbol whose name is the contents of
self
. -
is_alnum
Test the first character of self for the given condition. Returns false if
self
is empty. -
is_alpha
Test the first character of self for the given condition. Returns false if
self
is empty. -
is_digit
Test the first character of self for the given condition. Returns false if
self
is empty. -
is_lowercase
Test the first character of self for the given condition. Returns false if
self
is empty. -
is_uppercase
Test the first character of self for the given condition. Returns false if
self
is empty. -
print
Write self to standard output.
(Note that due to the development process, this is currently independent of the
File
class; it works by using the underlying C++ IO routines directly.) -
resize |new_size|
Change the size of
self
tonew_size
. If larger, the new characters are initialized 0.new_size
must not be negative. -
size
Return the length of
self
. -
str
Returns a human-friendly description of self. In this case, it's a copy in which all non-printable characters have been replaced by \xXX codes.
-
to_number
Given a string, parse it as one of the supported numeric types. It should really handle all of the numeric literal formats the parser does, but it doesn't. Maybe in the future?
-
unpack
Given a string, treat the first 8 bytes as an integer in network-order and return it as a Number. If there are fewer than 8 bytes, the missing bytes are presumed to be zero and on the most significant part of the number.
It is an error if Number cannot hold this value for some reason.
class Symbol < Object
Symbols are objects representing names. They are used by Loom itself to represent names in Loom code.
There is exactly one instance of each Loom symbol. Thus, for all
Symbols, if s == s
is true, then s === s
is also true.
It is not possible to create a subclass of MsgExpr
.
Inner methods
-
is_foldable
Can this object be reduced to something smaller? That is, if it's not fully foldable, can at least some of its subexpressions be fully folded?
Returns false if self is already trivially evaluable OR if it cannot be safely folded any further.
(See
Object::most_folded
for a longer explanation.) -
is_trivial_eval
Is this object trivial to interpret? (I.e. does the interpeter simply evaluate it to itself?)
-
str
-
unintern
Return a String containing the same text as
self
.
class Trait < Object
Abstract base class for all objects that have an inner method method dictionary. Provides methods for managing inner methods.
It can neither be instantiated or subclassed.
Inner methods
-
copy
Trait and derived classes are not copyable, so this returns
self
.(Well, they can be via clone, but it's much more valuable for them to be uncopyable and to prefer delegation.)
-
deepCopy
Trait and derived classes are not copyable, so this returns
self
.(Well, they can be via clone, but it's much more valuable for them to be uncopyable and to prefer delegation.)
-
inner_add_delegate |delegate|
Add a new AddonTrait to the list of inner delegates.
-
inner_add_method |name, method|
Add Method
method
toself
's inner method dictionary with namename
(a Symbol).method
must have been defined with a list of slots that exactly matches this trait's instances' list of slots or undefined behaviour may occur. -
inner_alias_method |from, to|
Create a new inner method dictionary entry named
to
that references the method named byfrom
. Both methods must belong toself
and not a delegate.from
andto
are symbols. -
inner_delegates
Return the list of inner delegates.
-
inner_get_method |name|
Retrieve the Method object associated with symbol
name
inself
s inner method dictionary. Fails if not present. -
inner_has_method |name|
Return true if
self
contains an inner method named bymethod
. Returns false if not, even when a delegate has it.
object True = Boolean.new
The True boolean value. (Also spelled true
).
Outer methods
-
& |other|
Perform a boolean and operation; return True if
self
andother
are both True and False otherwise. Bothself
andother
must be booleans. -
| |other|
Perform a boolean or operation; return True if
self
and/orother
is True and False if it isn't. Bothself
andother
must be booleans. -
if |body|
Evaluate
body
ifself === True
and don't ifself === False
.Returns the
body
's value if it's evaluated. -
not
Return the logical inverse of
self
.
class Vector < Object, Enumerable
Fundamental one-dimensional array type.
Cannot be subclassed.
Note: this implementation leans heavily on the underlying language's libraries. Future directions may split this into something more primitive and a Loom wrapper that puts back the convenient methods.
Outer methods
-
new |size|
Create a Vector of the specified size, filled with
nil
. If the size is zero or omitted, the vector is empty. -
with |*values|
Create a new vector initialized to the values of the arguments.
Inner methods
-
== |other|
Equality tests.
self
andother
are equal if and only if they are both vectors of the same length and corresponding elements are also equal according to==
. -
+ |other|
Return a copy of self with 'other' (an Enumerable) appended.
-
at |index|
Return the element at the given index. Fails if the index is invalid (<0 or >=
self.size
). -
atPut |index, value|
Set the value at
index
tovalue
and returnvalue
.index
must be between 0 and one less than the size ofself
. Fails if the index is invalid. -
deepCopy
Copy self and deeply copy all elements.
-
join |separator|
Ruby-style join method. Returns a string containing each item in
self
after a call tostr
withseparator
interleaved. -
pop
Remove (in place) and return the last item in Self. If empty, return nil.
-
push |value|
Append
value
to self in place, returning self. -
resize |new_size|
Change the size of
self
tonew_size
. If larger, the new slots are initialized tonil
.new_size
must not be negative. -
shift
Remove the first item from self and return it. Returns nil if empty.
-
size
Return the length of self.
-
str
Return a human-friendly string describing the contents of
self
. -
unshift |value|
Insert the argument at the beginning of 'self'.