haribote-lang is a simple and fast programming language for education originally made by Mr.Kawai.
This repository is a remodelled implementation in Rust of the original version, Creating programming languages in 10 days.
- This repository contains hrb, haribote-lang interpreter
- hrb runs in two modes, normal mode and interactive mode (a.k.a. REPL)
- Input source code is converted into internal code
- and is optimized it in several ways
For further information, See Optimization Strategy or My Blog(ja).
haribote-lang run on Windows, OSX, Linux, UNIX.
git clone https://github.com/tamaroning/haribote-lang.git
cd haribote-lang
cargo build --release
Run a .hrb file:
./target/release/hrb <filepath>
Run in an interactive mode:
./target/release/hrb
hrb [OPTIONS] FILEPATH
: Run the programhrb [OPTIONS]
: Run in interactive modehrb help
: show the usage
-emit-ir
: Display the intermidiate representation-no-optimize
: Doesn't optimize the program-no-exec
: Doesn't execute the program
In interactive mode, you can type an expression to check the result
?> hrb
haribote-lang version 1.1.1
Running in Interactive mode
Type "run <filepath>" to load and run the file.
>>> print "Hello World\n";
Hello World
>>> a = 15; b = 20;
>>> a * b
300
>>> exit
?>
?> hrb ./example/fibo.hrb`
Fibo_0 = 1
Fibo_1 = 1
Fibo_2 = 2
Fibo_3 = 3
Fibo_4 = 5
Fibo_5 = 8
Fibo_6 = 13
Fibo_7 = 21
Fibo_8 = 34
Fibo_9 = 55
Fibo_10 = 89
Fibo_11 = 144
?>
?> hrb -emit-ir example/calc.hrb
Optimizing...
--------------- Dump of internal code ---------------
copy a, i32 1
copy b, i32 3
copy _tmp0, i32 3
copy _tmp1, i32 4
copy c, i32 4
copy _tmp0, i32 8
copy _tmp1, i32 10
copy c, i32 10
-----------------------------------------------------
?>
- Num : Decimal numbers (0, 100, 53, 1024)
- Ident : Identifiers which starts with alphabet (abc, ABc123)
- Str : Strings encloses in double quotes ("Hello Hari-bote ", "World\n")
program ::= top*
top ::= label | stmt
label ::= <Ident> ":"
stmt :: = array-decl
| if-else
| for
| goto-stmt
| expr? ";"
| "print" (expr | <Str>) ";"
| "println" (expr | <Str>) ";"
array-decl ::= "let" <Ident> "[" expr "]" ";"
if-else ::= if-goto | if-else-sub
if-goto ::= "if" "(" expr ")" goto-stmt
if-else-sub ::= "if" "(" expr ")" "{" top* "}" ( "else" "{" top* "}" )?
for ::= "for" "(" expr? ";" expr? ";" expr? ")" "{" top* "}"
goto-stmt ::= "goto" <Ident> ";"
expr ::= assign
assign ::= equality ( ("=" | "+=" | "-=" | "*=" | "/=") expr )?
equality ::= relational ( ( "==" | "!=" ) relational )*
relational ::= add ( ( "<" | "<=" ) add )*
add ::= mul ( ( "+" | "-" ) mul )*
mul ::= unary ( ( "*" | "/" ) unary )*
unary ::= ("+" | "-")? primary
primary ::= <Num> | <Ident> ( "[" expr "]" )?
Intermidiate Representation (IR) is a low-level code of haribote language.
Optimizations are taken place on IR.
In order to learn how IR is implemented, see a struct Operation
in /src/parser.rs.
hrb supports the following optimization methods:
Basic strategy is as follows:
- Build a control-flow graph
- Data-flow analysis
- Change code
- Let each CFG node have a constant variable table.
- Information of constant variables moves to other nodes along the control flow. (One of the good ways is using a queue.)
- Replace arithmetic operations with copy operations by using information of the final stete.
- Let each CFG node n have a boolean value b[n].
- Set all b[n]s falses.
- Set b[entry point] true.
- Do BFS and set every b[reachable node] true.
- Remove n such that b[n] = false.
It's unnecessary to build a CFG.
- Search a
goto(jump) L
operation. L is a label. - If the distination label of L starts with a goto(jump) operation, get the destination of L.
- Repeat step 2. Finally get the final destination of label D.
- If detects a cyclic control-flow in step 3, do nothing and finish.
- Replace the original
goto(jump) L
withgoto(jump) D
.