5.2.6. Statements & Operators
Most of Spicy’s language constructs are pretty standard stuff. We
summarize them briefly in the following. We include Spicy’s statements
here, as well as some generic, non-trivial operators that aren’t
type-specific (e.g., new, begin). For operators specific to a
type, see the type’s documentation.
5.2.6.1. assert
assert EXPR;
assert EXPR : MSG;
Ensures at runtime that EXPR evaluates to a True value. If it
doesn’t, an exception gets thrown that will typically abort execution.
EXPR must either be of boolean type to begin with, or support
coercion into it. If MSG is specified, it must be a string or
error, and will be carried along with the
exception.
Note
Technically, the version providing a MSG isn’t a separate
syntax but just leveraging the condition test operator.
5.2.6.2. assert-exception
assert-exception EXPR;
assert-exception EXPR : MSG;
Ensures at runtime that evaluating EXPR triggers an exception. If
it indeed does, the exception is silently caught and execution
proceeds normally. If it doesn’t, an AssertionFailure exception is
triggered by the statement, which will typically abort execution. If
MSG is specified, it must be a string or error, and will be carried along with the exception.
5.2.6.3. begin
-
begin(<container>)→<iterator> Returns an iterator to the beginning of the container’s content.
5.2.6.4. break
break;
Inside a for or while loop,
break aborts the loop’s body, with execution then continuing
right after the loop construct.
5.2.6.5. confirm
confirm;
If the parser is currently in trial mode, confirm that the unit is successfully
synchronized to the input; the unit is then put into regular parsing mode
again. If the unit is not in trial mode confirm has no effect.
See reject to reject the synchronization instead.
confirm can only be invoked from hooks.
5.2.6.6. continue
continue;
Inside a for or while loop, continue
causes the remaining portion of the enclosing loop body to be skipped.
5.2.6.7. end
-
end(<container>)→<iterator> Returns an iterator to the end of the container’s content.
5.2.6.8. for
for ( ID in ITERABLE )
BLOCK
Loops over all the elements of an iterable value. ID is an
identifier that will become local variable inside BLOCK, with the
current loop element assigned on each round. ITERABLE is a value
of any type that provides iterators.
Examples:
module Test;
for ( i in [1, 2, 3] )
print i;
for ( i in b"abc" ) {
print i;
}
global v = vector("a", "b", "c");
for ( i in v )
print i;
# spicyc -j for.spicy
1
2
3
97
98
99
a
b
c
5.2.6.9. if
if ( EXPR )
BLOCK
if ( EXPR )
BLOCK
else
BLOCK
A classic if-statement branching based on a boolean expression
EXPR.
5.2.6.10. import
import MODULE;
Makes the content of another module available, see Modules for more.
5.2.6.11. new
-
new T→T& Returns a reference to an instance of a type newly allocated on the heap. If
Tis a type, a default instance of that type will be allocated. If the type expects any parameters, they must be provided through a corresponding argument tuple:new T(ARG_1, ... ,ARG_N). IfTis a constant, an instance of its type will be allocated and initialized with the value. Other types of expressions are not allowed.
5.2.6.12. pack
-
pack tuple→bytes Packs a value into a binary representation. See Packing / Unpacking Values for details.
5.2.6.13. print
print EXPR;
print EXPR_1, ..., EXPR_N;
Prints one or more expressions to standard output. This is supported for expressions of any type, with each type knowing how to render its values into a readable representation. If multiple expressions are specified, commas will separate them in the output.
Note
A particular use-case combines print with string interpolation
(i.e., string::Modulo):
module Test;
print "Hello, %s!" % "World";
print "%s=%d" % ("x", 1);
# spicyc -j print.spicy
Hello, World!
x=1
5.2.6.14. reject
reject;
If the parse is currently in trial mode, reject the synchronization; this immediately fails parsing of the unit and raises the parse error which caused the unit to be put into trial mode. If the unit is not in trial mode this triggers a generic parse error.
See confirm to confirm the synchronization instead.
reject can only be invoked from hooks.
5.2.6.15. return
return;
return EXPR;
Inside a function or hook, return yields control back to the
caller. If it’s a function with a non-void return value, the
return must provide a corresponding EXPR.
5.2.6.16. stop
stop;
Inside a foreach container hook (see here), aborts
the parsing loop without adding the current (final) value to the
container.
5.2.6.17. switch
switch ( [local IDENT =] CTRL_EXPR ) {
case EXPR [, ..., EXPR]:
BLOCK;
...
case EXPR [, ..., EXPR]:
BLOCK;
[default:
BLOCK]
}
Branches across a set of alternatives based on the value of an control
expression. CTRL_EXPR is compared against all the case
expressions through the type’s equality operator, coercing
CTRL_EXPR accordingly first where necessary. If local IDENT is
specified, the blocks have access to a corresponding local variable
that holds the value of the control expression. If no default is
given, the runtime will throw an UnhandledSwitchCase exception if
there’s no matching case.
Note
Don’t confuse the switch statement with the unit type’s
switch parsing construct. They look similar,
but do different things.
5.2.6.18. throw
throw EXPR;
Triggers a parse error exception with the message indicated by EXPR. EXPR needs
to be a String. throw aborts parsing.
5.2.6.19. typeinfo
typeinfo(TYPE)
typeinfo(EXPR)
Returns a value of type type, representing the given type, or the type of the given expression, respectively.
5.2.6.20. unpack
-
unpack type→<unpacked value> Unpacks a value from a binary representation. See Packing / Unpacking Values for details.
5.2.6.21. while
while ( COND )
BLOCK
while ( local IDENT = EXPR; COND )
BLOCK
while introduces a loop that executes BLOCK for as long as the
boolean COND evaluates to true. The second form initializes a new
local variable IDENT with EXPR, and makes it available inside
both COND and BLOCK.
5.2.6.22. : (Condition Test)
COND : ERROR
The condition test operator expects a boolean value as COND on
the left-hand-side, and a value of type error on
the right-hand-side. It returns a value of type result<void> that
will be set (i.e., evaluate to true) if COND is true; whereas it
will instead have its error set to the provided error value if
COND is false.
Example:
global x: result<void> = (4 == 5 : error"4 is not 5");
assert !x; # x holds error result
ERROR can also be given as a string, which will automatically be
converted to an error value. So this expression is equivalent to
the one above:
4 == 5 : "4 is not 5"