Lyvathon

Python as Lisp Dialect

Lyvathon Language Features

Lyvathon is a statically typed Java/Python hybrid in which all operators precede their operands, and parentheses are used for all grouping (except string literals, which as in Python are delimited with single or double quotes). Lyvathon code can be embedded in a LVM text file (Lyvathon Markup language). LVM is similar to HTML, except open tags begin with a brace bracket and a keyword, and the closing tag is simply a close brace bracket. Any text enclosed in a tag is preceded by a vertical slash (|). LVM also shares features of the Wikipedia markup language, so it's simpler than HTML.

Lyvathon is both a subset and superset of Python, except a given class can only inherit from a single base class (no multiple inheritance). Lyvathon borrows the interface feature from Java, in which the interface keyword is renamed to "scool". Two other new keywords include "scoolref" (built-in function returns a scool reference) and "abclass" (abstract class). File extensions include .LV (source code), .LVA (assembler code), .LVC (compiled code), and .LVM (Lyvathon Markup language).

Keyboard Aid

This optional feature enables hyphens, open parentheses, and close parentheses to be entered by typing single quotes, commas, and periods, respectively. When enabled, keyboard aid can be temporarily suppressed by using the Ctrl key in conjunction with typing single quotes, commas, and periods (no character substitution takes place). By convention, hyphens are used to separate words in multi-word identifiers, but single quotes are easier to type than hyphens. Similarly, commas and periods are easier to type than parentheses.

Special Characters

  • ()  grouping
  • -_  used in identifiers
  • ;  end of stmt.
  • :  dot operator
  • " '  string delimiters
  • \  escape char.
  • #  comment
  • {* *}  block comment

Grammar Notation

  • Non-terminal symbol: <symbol name>
  • Optional text in brackets: [ text ]
  • Repeats zero or more times: [ text ]...
  • Repeats one or more times: <symbol name>...
  • Pipe separates alternatives: opt1 | opt2
  • Comments in italics
  • Advanced features flagged as **

Compiler and Assembler

The Lyvathon Compiler translates source code into compiled code, and optionally into assembler code. Assembler code is an intermediate language which is much simpler than source code, although both source code and assembler code are in the form of text files. During Lyvathon development, the developer uses the Lyvathon Assembler, which converts assembler code (hand-written by the developer) into compiled code. This is a necessary step enabling the LYvathon Runtime Environment (LYRE) to be tested prior to the development of the Lyvathon Compiler.

Assembler Grammar

Each token is separated from adjacent tokens with white space. Parentheses count as tokens. Consecutive parentheses need no separating white space.

<source file>:

  • <module>...

<module>:

  • ( <mod>] [<global>] [<class>]... )

<global>:

  • ( module ( [<impmod>]... ) [<def>]... [<glbdef>] )

<class>:

  • ( <class id> ( [<mod>] <base id> )( [<var>]... ) [<def>]... )

<def>:

  • ( <id> ( [<parm>]... )( [<var>]... ) <block> )

<glbdef>:

  • ( global ( [<var>]... ) <block> )

<mod>:
<class id>:
<base id>:
<parm>:
<var>:

  • <id> // identifier

<impmod>:

  • <tupmod> [ ( <tuple>... ) ]

<tupmod>: // no spaces

  • <mod>
  • <mod> : <id>

<tuple>: // no spaces

  • <id>
  • <id> : <id>

<block>:

  • ( <hdr> [<tok>]... )

<tok>:

  • <keyword>
  • <expr>

<expr>:

  • <functok>
  • <vartok>
  • <const>
  • <block>
  • <dot expr>

<functok>: // no spaces

  • [[ <mod> : ] [<class id>]] : <id>

<vartok>: // no spaces

  • <id> // local var.
  • [[ <mod> : ] [<class id>]] : <id>

<const>:

  • <num> // integer
  • <float> // no. with dec. pt.
  • <string lit>

<hdr>:

  • <keyword>
  • <lvfunc>
  • <functok>

<lvfunc>:

  • <id> // built-in function

<dot expr>:

  • ( dot <vartok><dotelem>... )

<dotelem>:

  • <vartok>
  • ( <functok> [<expr>]... )

// must occur on line by itself
// no white space before #

<comment>:

  • # [<char>]...

Lyvathon Grammar

White space occurs between tokens (parentheses and semicolon need no adjacent white space, also any semicolon before a close parenthesis may be omitted):

<source file>:

  • [<line-comment>] [<vars>] [ do <block>] [<dec def>]... [<class>]... [ do <block>]

<import stmt>:

  • import <module>
  • import ( <module>... )
  • from <rel module> import <mod list>
  • from <rel module> import *

<module>:

  • <name>
  • ( <name> as <name> )
  • ( : <name>... [ as <name>] )

<mod list>:

  • <id as>
  • ( <id as>... )

<id as>:

  • <mod id>
  • ( <mod id> as <name> )

<mod id>:

  • <mod name>
  • <class name>
  • <func name>
  • <var name>

<rel module>:

  • ( <colon list> [<name>]... )
  • <name> // ?

<class>:

  • ( <cls typ> <name> [<base class>][<does>] [<vars>] do <dec def>... )
  • ( scool <name> [<does>] do [<const decl>]... [<dec hdr>]... )

<cls typ>:

  • class
  • abclass

<does>:

  • does ( <scool name>... )

<scool name>:
<base class>:

  • <name>
  • ( : <name><name>... )

<const decl>:

  • const <name><const expr> ;

<dec hdr>:

  • [<dec>]... <def hdr>

<dec def>:

  • [<dec>]... <def>

<dec>:

  • @ <call expr>

<def hdr>:

  • proc <name> ( [<var>]... )
  • func <type><name> ( [<var>]... )

<def>:

  • proc <name> ( [<var>]... ) [<vars>] do <block>
  • func <type><name> ( [<var>]... ) [<vars>] do <block>

<vars>:

  • var ( <var>... )

<var>:

  • [ static ] <type><name> ;
  • [ static ] <type> (<name>... ) ;

<type>:

  • <simple type>
  • <complex type>

<simple type>:

  • bool | int | long | float | double | array | dict |
  • lisp | bitarray | string | bytezero | bytes | func

<complex type>:

  • <class name>
  • ( <class name><method name> )

<block>:

  • ( <stmt-semi>... )

<stmt-semi>:

  • <stmt> ;

<stmt>:

  • pass
  • <if stmt>
  • <while stmt>
  • <for stmt>
  • ** <try stmt>
  • <disruptive stmt>
  • <call stmt>
  • <asst stmt>
  • <del stmt>
  • <print stmt>
  • <import stmt>

<disruptive stmt>:

  • <continue stmt>
  • <break stmt>
  • <return stmt>
  • ** <raise stmt>

<call expr>:

  • ( <name> [<expr>]... )
  • ( : <obj expr> [<colon expr>]... ( <method name> [<expr>]... ))
  • ( call <expr>... )

<call stmt>:

  • ( <name> [<expr>]... )
  • : <obj expr> [<colon expr>]... ( <method name> [<expr>]... )
  • call <expr>...

<colon expr>:

  • <name>
  • ( <name> [<expr>]... )

<asst stmt>:

  • <asst op><name><expr>
  • <asst op><target expr><expr>

<asst op>:

  • set | addset | minusset | mpyset | divset |
  • idivset | modset | shlset | shrset |
  • andset | orset | xorset

<target expr>:

  • ( : <name> [<colon expr>]... <name> )
  • ( slice <arr><expr> [<expr>] )
  • ( slice <arr><expr> all )

<arr>:   string or array

  • <name>
  • <expr>

<if stmt>:

  • if <expr><block> [ elif <expr><block>]... [ else <block>]

<while stmt>:

  • while <expr> do <block>
  • do <block> while <expr>

<for stmt>:

  • for <name> in <expr> do <block>
  • for <name> ( <expr><expr>< [expr>] ) do <block>

<try stmt>:

  • try <block> <except clause>... [ else <block>] [ finally <block>]
  • try <block> finally <block>

<except clause>:

  • except <name> [ as <name>] <block>

<raise stmt>:

  • raise [<expr> [ from <expr>]]

<return stmt>:

  • return [<expr>]

<break stmt>:

  • break

<continue stmt>:

  • continue

<del stmt>:

  • del <expr>

<print stmt>:  // built-in function

  • ( print [<expr>]... )
  • ( echo [<expr>]... )

<expr>:

  • <keyword const>
  • <literal>
  • <name>
  • ( <unary op><expr> )
  • ( <bin op><expr><expr> )
  • ( <multi op><expr><expr>... )
  • ( quest <expr><expr><expr> )
  • <array expr>
  • <dict expr>
  • <bitarray expr>
  • <string expr>
  • <bytezero expr>
  • <bytes expr>
  • <target expr>
  • <obj expr>
  • <cast>

<obj expr>:

  • <name>
  • <call stmt>

<unary op>:

  • minus  negate
  • notbits  bitwise not
  • not

<bin op>:

  • <arith op>
  • <comparison op>
  • <shift op>
  • <bitwise op>
  • <boolean op>

<arith op>:

  • div | idiv | mod | mpy | add | minus

<comparison op>:

  • ge | le | gt | lt | eq | ne | is | in

<shift op>:

  • shl | shr

<bitwise op>:

  • andbits | orbits | xorbits

<boolean op>:

  • and | or | xor

<multi op>:

  • mpy | add | or | and |
  • strdo  % operator
  • strcat  + operator

<const expr>:

  • <literal>
  • <keyword const>

<literal>:

  • <num lit>
  • <string lit>
  • <bytes lit>

<array expr>:

  • ( array [<expr>]... )

<bitarray expr>:

  • ( bitarray [<expr>] )

<dict expr>:

  • ( dict [ <pair>]... )

<pair>:

  • ( <name><expr> )
  • ( <literal><expr> )

<cast>:

  • ( cast <type><expr> )

<lisp funcs>:

  • ( quote <expr> )
  • ( compile <expr> )
  • ( exec <expr> )

The quote function takes a block of code and treats it like data, with an implied list keyword after every open parenthesis. The compile function compiles the output of the quote function, which is then executed by the exec function.


No white space allowed between tokens, for rest of Lyvathon Grammar:

<white space>:

  • <white token>...

<white token>:

  • <rest-comment>
  • <non-line-comment>

<rest-comment>:

  • <non-line-comment><line-comment>

<line-comment>:

  • # [<char>]... <new-line>

<non-line-comment>:

  • <white char>
  • <blk-comment>

<blk-comment>:

  • {* [<char>]... *}

<white char>:

  • <space> | <tab> | <new-line>

<name>:

  • [<underscore>]... <letter> [<alnum>]... [<hyphen-alnum>]... [<underscore>]...

<hyphen-alnum>:

  • <hyphen><alnum>...

<alnum>:

  • <letter>
  • <digit>

In plain English, names begin and end with zero or more underscores. In between is a letter followed by zero or more alphanumeric characters. Names may also contain hyphens, where each hyphen is preceded and succeeded by an alphanumeric character.

<num lit>:

  • <dec int>
  • <oct int>
  • <hex int>
  • <bin int>
  • <float>

<dec int>:

  • 0
  • [<hyphen>] <any digit except 0> [<digit>]...

<float>:

  • <dec int> <fraction> [<exponent>]
  • <dec int> <exponent>

<fraction>:

  • <dot> [<digit>]...

<exponent>:

  • <e> [<sign>] <digit>...

<e>:

  • e | E

<sign>:

  • + | -

<oct int>:

  • 0o <octal digit>...

<hex int>:

  • 0x <hex digit>...
  • 0X <hex digit>...

<bin int>:

  • 0b <zero or one>...
  • 0B <zero or one>...

<octal digit>:

  • 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7

<hex digit>:

  • <digit>
  • A | B | C | D | E | F
  • a | b | c | d | e | f

<keyword const>:

  • None
  • True
  • False

<colon list>:

  • : [ : ]...

<string lit>:

  • [<str prefix>] <short long>

<str prefix>:

  • r | u | R | U

<short long>:

  • ' [<short item>]... '
  • " [<short item>]... "
  • ''' [<long item>]... '''
  • """ [<long item>]... """

<short item>:

  • <short char>
  • <escaped str char>

<long item>:

  • <long char>
  • <escaped str char>

<short char>:

  • any source char. except "\", newline, or end quote

<long char>:

  • any source char. except "\"

<bytes lit>:

  • <byte prefix><shortb longb>

<byte prefix>:  any case/order

  • b | br

<shortb longb>:

  • ' [<shortb item>]... '
  • " [<shortb item>]... "
  • ''' [<longb item>]... '''
  • """ [<longb item>]... """

<shortb item>:

  • <shortb char>
  • <escaped char>

<longb item>:

  • <longb char>
  • <escaped char>

<shortb char>:

  • any ASCII char. except "\", newline, or end quote

<longb char>:

  • any ASCII char. except "\"

<escaped char>:

  • \newline  ignore backslash, newline chars.
  • \\  backslash
  • \"  double quote
  • \'  single quote
  • \a  bell
  • \b  backspace
  • \f  formfeed
  • \n  new line
  • \r  carriage return
  • \t  tab
  • \v  vertical tab
  • \ooo  octal value = ooo
  • \xhh  hex value = hh

<escaped str char>:

  • <escaped char>
  • \N{name}  Unicode char. = name
  • \uxxxx  hex value (16-bit) = xxxx
  • \Uxxxxxxxx  hex value (32-bit) = xxxxxxxx

Semicolon Grammar

The semicolon switch (the default) allows statements normally enclosed in parentheses to instead be terminated with semicolons, with no need for whitespace surrounding semicolons (similar to parentheses). What follows assumes the switch is off, and statements are enclosed in parentheses.

<import stmt>:

  • ( import <module> )
  • ( import ( <module>... ))
  • ( from <rel module> import <mod list> )
  • ( from <rel module> import all )

<def>:

  • ( proc <name> ( [<var>]... ) [<vars>] do <stmt>... )
  • ( func <type><name> ( [<var>]... ) [<vars>] do <stmt>... )

<block>:

  • ( <stmt>... )

<raise stmt>:

  • ( raise [<expr> [ from <expr>]] )

<return stmt>:

  • return
  • ( return <expr> )

<if stmt>:

  • ( if <expr><block> [ elif <expr><block>]... [ else <block>] )

<while stmt>:

  • ( while <expr> do <stmt>... )
  • ( do <block> while <expr> )

<for stmt>:

  • ( for <name> in <expr> do <stmt>... )
  • ( for <name> ( <expr><expr>< [expr>] ) do <stmt>... )

<try stmt>:

  • ( try <block> <except clause>... [ else <block>] [ finally <block>] )
  • ( try <block> finally <block> )

<call stmt>:

  • ( <name> [<expr>]... )
  • ( : <obj expr> [<colon expr>]... ( <method name> [<expr>]... ))
  • ( call <expr>... )

<asst stmt>:

  • ( <asst op><name><expr> )
  • ( <asst op><target expr><expr> )

<del stmt>:

  • ( del <expr> )

<print stmt>:

  • ( print [<expr>]... )
  • ( echo [<expr>]... )

Keyword Switch

When this switch is disabled (enabled by default), many keywords such as {gt, le, set} are instead abbreviated using non-alphanumeric characters: {>, <=, =}.

[ Back to Top ]