The Structure of Trylid Code

Names

Words are separated by whitespace, and can contain most non-whitespace characters, including UTF-8 characters. In particular, they can contain hyphens ('-'); use of hyphens is encouraged so separate words in a name (as opposed to the use of underscores or camelCase). However, a name may not start with a hyphen. Similarly, a name may contain digits but may not start with one. A name may contain periods ('.'); beginning a name with a period is a way of indicating that the name is normally to be hidden from human eyes (as in the Unix filesystem).

The following characters are not allowed in names:

# " ' ` ( ) [ ] { } ; ~ = + * / % ^ < > & | ,
Lines and Blocks

Like Python, Trylid code is organized by lines and indented blocks. An indented block is "owned" by the line above it; in a way, it can be thought of as being a part of that line.

If a line is too long to fit on the screen, it can be continued with "--" at the end of the line. Then the following line (minus its indentation, which is ignored) will be considered part of that line.

if some-value == "this" || some-value == "that" || -- some-value == "the-other" || -- some-value == "yet-something-else" do-something

The meaning of a line will depend on the current syntax, but might be changed by the first word on the line:

# In the method syntax, most lines are expressions: foo = bar + baz # But some words introduce special forms: if x < y do-something for item in collection print-line: item string

Similarly, the syntax of a block is usually determined by its owning line, but the first word of a block may indicate that the block is in a different syntax:

print-line: string coke (send (quote print:) StdOut string) usage = text You may be wondering how to use this program. ... and someday there'll be instructions here on how to do it.

[*Not yet implemented*: See the "Implementation Quirks" section for an explanation of how the above two examples would currently be done.]

The Two Syntaxes

Trylid has two block-level syntaxes. One is the "prototype" syntax, defining methods and other elements of a prototype:

superclass SuperProto fields name collection help-text = "Help text goes here." # A "shared field". num-items return collection num-items for-each: block for item in collection block value: item proto SubProto # Another prototype in the "namespace" of the current proto. fields name value

Lines in the "prototype" syntax are function declarations (with their associated code blocks), shared-field declarations (using "="), or special forms like "fields" or "proto".

The other is the "method" syntax, for code within a method:

frobnify: index adjusted-index = index # Auto-declaration of a local. if adjusted-index > max-index adjusted-index = max-index print-line: "Frobnification complete."

Lines within the "method" syntax are either expressions, assignments (technically, assignments are also expressions, and if the name being assigned to doesn't exist in an outer scope, a local is auto-declared in the current block), and special forms like "if", "while", "for", etc.

Prototypes in the Filesystem

Most prototypes will have a file in the filesystem with the source code to define it. Since prototypes may also act as namespaces for other prototypes, a prototype may also be specified by a directory, with files (or directories) for its sub-prototypes and (optionally) a file called "main" with source code for defining methods, fields, etc.

A typical project will live in a directory, with its sources in a subdirectory called "sources":

my-project/ Notes to-do build-settings sources/ main Screen Window XWindows/ Screen Window Carbon/ Screen Window

Note that this could have all been defined within one file ("sources/main"), if that were more convenient:

trylid main proto Screen # ... proto Window # ... proto XWindows proto Screen # ... proto Window # ... proto Carbon proto Screen # ... proto Window # ...