Skip to content

Commit

Permalink
preparing for releasing 0.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
cheery committed Dec 31, 2015
1 parent 1536d0d commit 0217488
Show file tree
Hide file tree
Showing 57 changed files with 29,543 additions and 7 deletions.
258 changes: 251 additions & 7 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
Welcome to Lever's documentation
================================

0.5.0 is a draft of the Lever programming language. The documentation is incomplete.
0.5.0 is an early release of the Lever programming language. This documentation
is incomplete.

Stable releases will come with complete documentation. For most things not described here, I advice you to `join the irc channel set up for the community`_.
Stable releases will come with complete documentation. For most things not
described here, I advice you to `join the irc channel set up for the community`_.

.. _join the irc channel set up for the community: http://webchat.freenode.net/?randomnick=1&channels=%23lever&prompt=1

Expand All @@ -19,21 +21,39 @@ Contents:

stdlib

Compiling Instructions
======================
Installing Lever
================

There are some things that may need explicit platform support and I'll be busy coding
the first programs in the language. Therefore I only promise that Linux version runs.
There are some things that may need explicit platform support and I'll be busy
coding the first programs in the language. Therefore I only promise that Linux
version runs.

At maximum there will be a release for the SteamOS, so you have to compile this
yourself. If you happen to be a person doing packaging for a distribution, please
provide your contact info so that I can assist you out and help keep the packaging
updated effortlessly.

Obtain the source code
----------------------

Easiest way to obtain Lever source code is to use git. Git also helps
tremendously if you later decide to contribute to lever. To download yourself a
repository you can contribute to, do::

git clone https://github.com/cheery/lever

At any time, you may also download an archive snapshot of the repository and extract::

wget https://github.com/cheery/lever/archive/master.zip
unzip master.zip

Compiling instructions
----------------------

Fortunately the compiling will only take few minutes and it's easy. I have set up a
script to compile lever. Here's how to invoke it from a terminal::

cd path/to/lever
cd lever
python setup.py compile

If you're on debian based system, it prompts to install what you need to compile it.
Expand All @@ -45,7 +65,231 @@ used to run any of the examples. Here's how to run one of the samples::

python run.py samples/ticktock.lc

Languages present in Lever runtime
==================================

Lever currently uses python for scripts and for compiling from source code to
bytecode. Though it is its own language.

The interpreter is written in RPython. From there it is translated into native
machine code and a matching JIT compiler is generated.


Lever syntax & grammar
======================

Before lever runs a source listing, it compiles that into instructions so that
virtual machine can load in the program. Instead of having a grammar in itself,
the compiler loads it as an input from the lever.grammar -file.

The lever.grammar is a listing of context-free rules the compiler recognizes.
If you happen to prefer different syntax for some reason, all you need to do is
change the lever.grammar and provide it along your project.

There is a thin layer of tokenizing before the grammar is applied to the input
source listing.

If you have used dynamically typed languages before, and you know what a
context free grammar is, most of this grammar should make sense.

The functions processing each of these rules are in compile.py, and they are
prefixed with post\_.

Blocks
------

Lever files are sequences of statements separated by newline. Each statement
can be evaluated and when done so return a value, these statements are called
blocks, whenever appropriate, increased indentation level can form a block
inside expressions::

file =>
empty_list:
statements

block => pass(statements): indent statements dedent

statements =>
first: block_statement
append(lhs rhs): lhs=statements newline rhs=block_statement

Different statements
--------------------

The statement is divided into block-level and ordinary statements. Right now,
expressions are the only ordinary statements::

block_statement =>
pass: statement
return(statement):
kw_return:"return" statement
if(statement block otherwise):
kw_if:"if" statement block otherwise
while(statement block):
kw_while:"while" statement block
local_assign(symbol block_statement):
symbol assign_op:"=" block_statement
upvalue_assign(symbol block_statement):
symbol upvalue_assign_op:":=" block_statement
setitem(expr idx block_statement):
expr lb:"[" idx=expr rb:"]" assign_op:"=" block_statement
setattr(expr symbol block_statement):
expr dot:"." symbol assign_op:"=" block_statement
for(symbol statement block):
kw_for:"for" symbol kw_in:"in" statement block
import(symbols_list):
kw_import:"import" symbols_list

otherwise =>
done:
elif(statement block otherwise):
newline kw_elif:"elif" statement block otherwise
else(block):
newline kw_else:"else" block

statement =>
pass: expr

Note that on topmost level function, the local_assign assigns a value into
module namespace rather than the local scope.

The upvalue assign -rule can be used to store values into already bound variables.

I have also not entirely decided how variable lookup should happen. Right now,
lookup happens from local scope, if there is a preceding dominating control
flow block that does local_assign into that variable. This is a cornel case and
the behavior may change, though.

Expressions
-----------

Expressions are some of the few things that might be easier to describe with
precedence table. For now, you can take a thumb of rule that the rule appearing
lower in this subsequent listing will take higher precedence::

expr =>
expr3
or(expr3 expr): expr3 kw_or:"or" expr

expr3 =>
expr5
and(expr5 expr3): expr5 kw_and:"and" expr3

expr5 =>
expr8
not(expr8): kw_not:"not" expr8

expr8 =>
expr10
in(l r): l=expr10 kw_in:"in" r=expr10
not_in(l r): l=expr10 kw_not:"not" kw_in:"in" r=expr10
binary: expr10 lt:"<" expr10
binary: expr10 gt:">" expr10
binary: expr10 eq:"==" expr10
binary: expr10 ne:"!=" expr10
binary: expr10 le:"<=" expr10
binary: expr10 ge:">=" expr10

expr10 =>
expr20
binary: expr10 bitwise_or:"|" expr20
expr20 =>
expr30
binary: expr20 bitwise_xor:"^" expr30

expr30 =>
expr50
binary: expr30 bitwise_and:"&" expr50

expr50 =>
expr100
binary: expr50 bitwise_shl:"<<" expr100
binary: expr50 bitwise_shr:">>" expr100

expr100 =>
expr200
binary: expr100 concat:"++" expr200
binary: expr100 plus:"+" expr200
binary: expr100 minus:"-" expr200

expr200 =>
prefix
binary: expr200 star:"*" prefix
binary: expr200 slash:"/" prefix
binary: expr200 percent:"%" prefix

prefix =>
postfix
prefix: plus:"+" postfix
prefix: minus:"-" postfix

postfix =>
term
call(postfix arguments):
postfix lp:"(" arguments rp:")"
getitem(postfix expr):
postfix lb:"[" expr rb:"]"
getattr(postfix symbol):
postfix dot:"." symbol

arguments =>
empty_list:
arguments1
pass(arguments1): arguments1 comma:","

arguments1 =>
first: expr
append(lst expr): lst=arguments1 comma:"," expr

Terms
-----

These are the current terms understood by the language::

term =>
lookup: symbol
int: int
hex: hex
float: float
string: string
pass(expr): lp:"(" expr rp:")"
list(arguments): lb:"[" arguments rb:"]"
function(bindings block):
lp:"(" bindings rp:")" colon:":" block
dict(pairs): lc:"{" pairs rc:"}"
lookup(escaped_keyword): lc:"{" escaped_keyword rc:"}"
lookup(string): percent:"%" string

bindings =>
empty_list:
bindings1
pass(bindings1): bindings1 comma:","

bindings1 =>
first: symbol
append(lst symbol): lst=bindings1 comma:"," symbol

pairs =>
empty_list:
pairs1
pass(pairs1): pairs1 comma:","

pairs1 =>
first: pair
append(lst pair): lst=pairs1 comma:"," pair

pair => tuple(k v): k=expr colon:":" v=expr

escaped_keyword =>
pass: kw_import:"import"
pass: kw_and:"and"
pass: kw_or:"or"
pass: kw_not:"not"

symbols_list =>
first: symbol
append(lst symbol): lst=symbols_list comma:"," symbol

Lever base module
=================
Expand Down
4 changes: 4 additions & 0 deletions www/doc/0.5.0/.buildinfo
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: e0727f78e425fbc1eb21ca3da4ba7f38
tags: 645f666f9bcd5a90fca523b33c5a78b7
Binary file added www/doc/0.5.0/_images/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 0217488

Please sign in to comment.