To precisely describe what can be interpreted as meaningful by the OpenEuphoria engine, some conventions are needed. They were described at the very beginning of part A, but it may be useful to state them again here.
typewriter-like
fashion.
The vertical bar ( | ) will denote a choice to be made among a finite number of options, like in for | if | while.
This section enumerates the various syntactic entities that form an OpenEuphoria program, and the allowed arrangements of them.
program::=
statement
statement::=
includer |
var_decl | routine
forwarding | routine | struct | general-code
includer::=
include filename | (filename) [as identifier] |
import filename [as identifier] |
promote [but] "{identifier}" | identifier [from identifier] |
promote _ from identifier |
demote [but] "{identifier}" | identifier [from identifier] |
demote _ from identifier
Note that the from clause is mandatory when demote but is used.
filename::=
Consecutive characters in a row, possibly between double quotes | an expression between parentheses, whose value will be taken as an immediate file name to be passed to the OS.
identifier::=
One or more printable alphanumeric characters, starting with a letter. Identifiers are case sensitive, so that foo, Foo, FOO, etc... are all different identifiers.
general_identifier::=
identifier[index_levels] [[[expr]]]
index_levels::= index_level[index_levels]
index_level::= [ expr | expr..expr]
The second form of basic_index is called a slice.
letter::=
Any character with ASCII code in the range 65-90,97-122,128-255, or any Unicode double-byte character greater than 256. Additional interpreter specific restrictions may be enforced.
printable alphanumeric character::=
letter | digit | _
digit::=
Any in the ASCII range 35,48-57,65-70,97-102. Note that the # sign can appear only before digits, and that the letters a-f and A-F are digits only if the number they are in starts with #.
scope block::=
scope [identifier]
statement
end scope
routine forwarding::= forward routine definition
routine definition::=
[rattr ]rttype identifier({[update ]type identifier})
rttype::=
routine | coroutine | reftype | type | procedure | function | handler
rattr::= forward | global| check
Note that check is only valid for type and reftype routine types.
type::=
boolean | object | char | integer | atom | fraction | nonatomic type | user-defined
type
user-defined type::=identifier
nonatomic type::=
array(number) [of type] | sequence [of type]
of object is assumed if the of clause is omitted.
number::=
#[-]hexdigit | [- | +]decdigit
hexdigit::=
Any character in ASCII range 48-57,65-70,97-102, or, in other words, '0'-'9', 'A'-'F','a'-'f'. The underscore ("_") is also allowed as visual separator for groups of digits, but underscores must not start a number.
decdigit::=
any character in ASCII range 48-57, or '0'-'9'. The underscore ("_") is also allowed as visual separator for groups of digits, but underscores must not start or end a number.
routine::=
routine definition
[var-decl]
[general-code]
end rttype
Note that the last rttype must match the one in routine definition.
var_decl::=
type {identifier[=expr]} | constant {[type] identifier=expr}
Note that the above lists should not be empty. If the type is not specified, the object type is assumed.
struct::=
structure identifier({type | _ identifier | _}) end structure
memory identifier({exttype identifier | _}) end memory
exttype::=
[optional ][[un]signed ][counted(number)|delimited(list)] (predefined type | byte(number)) [(number)]
general-code::=
procedure call | assignment | action | loop | if
block | select block |
flow | comment | other | dynamic |
with optname |
without optname
dynamic::=
execute(expr) | call_func(expr,list) |
call_proc(expr,list) | call_routine(expr,list) |
resume_execute(expr) | return_execute(expr)
list::={{expr}} | expr
attr::=byval | byref
procedure call::=identifier({[attr ]expr})
assignment::=
identifier[: | operator]=expr |
#({identifier})[operator]=expr |
#({identifier})#[operator]=expr
See specific usage notes about the third form in sections 5.5.2 in part A.
operator::= any listed in 1.3.1 in part A.
action::=
label identifier | name general_identifier as identifier | rename general_identifier as identifier | unname general_identifier | ?expr
flow::=
exit [number | identifier] | exif [number | identifier] |
next [number | identifier] | retry [number | identifier] |
break [number | identifier] | return [expr] |
yield [expr] | extended_return(integer,[expr]) |
goto identifier | goto_far(namespace,identifier) |
come_from[_far]() | come_back[_far]
Note that break is only allowed inside a select block; exit, next and retry are allowed only inside a loop; exif is allowed only inside an if block; return is allowed only inside routines.
loop::=
lptype lpparm do general-code end lptype
The starting and ending lptype tokens must match. lpparm depends on lptype; see individual entries for more details.
lptype::= for | while | wfor
if block::=
if cond then
general-code
[elsif cond then
general-code]
[else general-code]
end if
cond::=
[not] clause [logical cond]
logical::=and | or | xor
clause::=
routine call | expr rel_op expr | (expr rel_op expr) rel_op::= < | <= | = | != | > | >=
expr::= identifier[@meta] | number | expr op expr | (expr op expr) | routine call
meta::= name | assigned | value | size | type | id | deftype | scope | format | types | decl_mode
select block::=
select expr
[case shortcond: general-code]
[otherwise general-code]
end select
shortcond::=<
expr | expr thru expr | rel_op expr
You can use the anonymous variable "_" inside a shortcond to refer to the value of the selector of the surrounding select block.
comment::=--characterline_end
whitespace::=tab | space | line_end
line_end::=newline | carriage return
A source file is a file of any extension (if the concept is supported by the host OS) made of (possibly unicode) characters arranged in logical lines. Logical lines start at the top of the file or after a line_end, and they end with a line_end or the end of the file, which does not need any special control character.
Lines are made of whitespace and non-whitespace characters. Consecutive whitespace are coalesced to one. In some cases, an absent whitespace character is assumed, or an existing whitespace is ignored.
all_short_circuit | enables short-circuit evaluation of conditionals wherever there's any. This flag is on by default, but can be toggled off for backward compatibility with Eu. RDS Eu only uses short-circuit evaluation in the conditional clauses of the if, esif and while statements. | |
byref | makes the use of byref and byval keywords mandatory for arguments passed by reference. | |
events[=list] | enables or disables before/after pairs of events. The available list of pairs is:
| |
profile | turns profiling facility on | |
RDS | turns seq_compat on, and turns rounding, all_short_circuit, and events off | |
rounding[=value] | turns rounding of floatiing point numbers before compare on. A granularity value must be supplied on first invocation of this directive. | |
seq_compat | turns extension of relational operators to nonatoms on | |
trace | turns trace facility on | |
type_check | turns systematic type checking on assignment on | |
warning[=list] | specifies the warnings to be turned on. No optional list means all kinds of warnings are enabled. |
The warnings issued by OpenEuphoria are as follow:
- UnusedPrivateVar --a private variable is not referenced in the routine
- UnusedFormalParm --a routine does not use some of its formal parameter
- ShadowingDefaultGlobal --a global symbol in default: is being shadowed by another global.
- ShortCircuitSideEffect --an expression with side effects is bypassed because of short circuit evaluation
- StatementAfterReturn --rncountered a statement following a return instruction which cannot be executed.
- VariableIsWriteProtected -- attempt to write to a locked variable.
- OverridingBuiltin -- a symbol from builtin: is being shadowed