Lunar Programming Language

by David A. Moon
January 2017 - January 2018



Program Representation

The source code of a program is parsed into expression objects which represent its semantics. These objects can be compiled into executable code.

The basic type is

def literal = number | character | string
def expression = name | literal | quotation | compound_expression | block_scope
Thus an expression can be a name which can be looked up in a scope to yield its definition, or a constant number | character | string | quotation, or some subclass of one of the abstract classes compound_expression and block_scope which represent an action.

The compound expressions are:

defclass call_expression(function expression, parameters expression...) compound_expression
represents a call to the given function with the given actual parameters.

defclass spread_call_expression(function expression, parameters expression...) call_expression
represents a call with ... after the last actual parameter.

defclass prog_expression(expressions expression...) compound_expression
represents a sequence of expressions whose result is the result of the last expression. It has no bearing on scopes.

abstract:
defclass block_scope(expressions expression...) local_scope
  expressions := expressions  sequence[expression]
represents both the local scope of a block and the expressions in that scope. Its result is the result of the last expression. The expressions slot can be modified during parsing, but not afterwards. Any definitions present in the expressions are local to this scope. For correct implementation of the scoping rules, all definitions should precede all non-definitions in the expressions. A block_scope is both an expression and a scope. This is an abstract class with two subclasses. It does not inherit from compound_expression because compound_expression has slots, so that would violate the consistent slot order rule.

defclass block_head_scope(expressions expression...) block_scope(expressions...)
represents the entirety of a block.

defclass block_tail_scope(expressions expression...) block_scope(expressions...)
represents all expressions after a specific definition in a block. This is distinct from block_head_scope because a definition in a block creates a new local scope that does not include expressions earlier in the block.

defclass if_expression(test expression, consequent expression, alternate expression) compound_expression
represents a conditional test. consequent is only executed if the result of test is true. alternate is only executed if the result of test is false. The result of the if_expression is the result of whichever one is executed.

defclass assignment_expression(lhs name, rhs expression) compound_expression
represents an assignment statement that changes the value of the variable lhs to the result of rhs, which is also the result of the statement.

abstract: defclass definition compound_expression
represents any definition statement.

Information about a definition in a scope is a subclass of definition. At compile time, scopes contain definitions which remember what we know about how names are defined in that scope. A definition object also represents the expression that creates the definition.

At run time, local scopes have been compiled away. Modules contain global definitions and their associated value cells and remain available at run time so new code can be loaded.

defclass known_definition(name name, value everything) definition
represents a constant definition whose value is known at compile time.

def known_definition(name name, value everything) ...
is the constructor for known_definition.
def known_definition(scope scope, name name) ...
looks up the definition of name in scope. If it's a known_definition, the result is the value of that definition, otherwise the result is false. Note that you cannot distinguish a known definition as false from no definition, nor from a definition whose value is not known at compile time.

defclass constant_definition(name name, type type, expression expression) definition
represents a definition whose value is constant but not known at compile time. At run time, the expression expression is executed and its result is the value. The value cannot be changed by assignment. There is also a value slot, which is a value cell used at runtime for global definitions only.

defclass variable_definition(name name, type type, expression expression) definition
represents a definition whose value can be changed at run time by assignment. At run time, the expression expression is executed and its result is the initial value. There is also a value slot, which is a value cell used at runtime for global definitions only.

require assignable?(def definition) => boolean
is true if the definition's value can be changed by assignment.

defclass formal_parameter_definition(name                        name,
                                     type                        type,
                                     optional:
                                     default = false             expression | false,
                                     scope_for_default = false   scope | false,
                                     selector = false            name | false
                                     ) definition
represents a formal parameter of a method. There is also an inferred_type slot used by the compiler.

The default slot is only filled in optional and named parameters. If it is filled, the scope_for_default slot contains the scope in which the default expression should be evaluated.

The selector slot is only filled in named parameters. It contains the name of the keyword that selects this formal parameter, with any hygienic context removed.

defclass method_expression(name                 name | false,
                           formal_parameters    formal_parameters,
                           result_type          type,
                           modifiers            method_modifiers | false
                           body                 expression) compound_expression

;; Abbreviated pseudo-constructor
def method_expression(head method_head, body expression)
  method_expression(head.name, head.formal_parameters, head.result_type,
                    head.modifiers and not empty?(head.modifiers) and head.modifiers,
                    body)
A method_expression results in a method object when executed. It can be passed to add_method to become part of a function bundle or can be called directly.

TODO cross-reference other compound_expression subclasses explained elsewhere

TODO explain exit_expression and finally_expression somewhere

TODO source_locators


Previous page   Table of Contents   Next page



Creative Commons License
Lunar by David A. Moon is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
Please inform me if you find this useful, or use any of the ideas embedded in it.
Comments and criticisms to dave underscore moon atsign alum dot mit dot edu.