Watch one program become machine work.
Follow a real program through five compiler stages, from source to result, then run your own in Venutian's own compiler.
The stepper
Follow one program through Source, Tokens, Syntax tree, Bytecode and Result. Every panel shows real output captured from the compiler at build time.
hello hello.ven
Source
The program exactly as it sits in the file, the text the compiler reads.print "Hello from Venutian"Tokens
The venutian tokens command cuts that text into words, each with its kind, its value, its line and its column.- PRINTprintline 1 column 1
- TEXT"Hello from Venutian"line 1 column 7
- NEWLINEline 1 column 28
- EOFline 3 column 1
Syntax tree
The venutian ast command shows the grammar the parser found: every statement a node, every name and literal a leaf.- Program
- statements
- PrintStatement
- args
- TextLiteral value "Hello from Venutian"
- args
- PrintStatement
- statements
- Program
Bytecode
The venutian disasm command lists the instructions the virtual machine runs, each operand resolved to the constant it names.main Offset Instruction Operand Constant 0 LOAD_CONST 0 "Hello from Venutian" 1 PRINT 1 2 HALT Output
The venutian run command compiles the program and runs it on the native virtual machine, and this is what it printed.Hello from Venutianexit 0
grade guards.ven
Source
The program exactly as it sits in the file, the text the compiler reads.make grade(score) choose score is n: Integer where n >= 90 give "A" is n: Integer where n >= 80 give "B" is n: Integer where n >= 70 give "C" is : Integer give "F" otherwise give "not a number"print grade(95)print grade(82)print grade(71)print grade(50)print grade("ninety")Tokens
The venutian tokens command cuts that text into words, each with its kind, its value, its line and its column.- MAKEmakeline 1 column 1
- IDENTgradeline 1 column 6
- LPAREN(line 1 column 11
- IDENTscoreline 1 column 12
- RPAREN)line 1 column 17
- NEWLINEline 1 column 18
- INDENT4line 2 column 1
- CHOOSEchooseline 2 column 5
- IDENTscoreline 2 column 12
- NEWLINEline 2 column 17
- INDENT8line 3 column 1
- ISisline 3 column 9
- IDENTnline 3 column 12
- COLON:line 3 column 13
- IDENTIntegerline 3 column 15
- WHEREwhereline 3 column 23
- IDENTnline 3 column 29
- GE>=line 3 column 31
- INTEGER90line 3 column 34
- NEWLINEline 3 column 36
- INDENT12line 4 column 1
- GIVEgiveline 4 column 13
- TEXT"A"line 4 column 18
- NEWLINEline 4 column 21
- DEDENT8line 5 column 1
- ISisline 5 column 9
- IDENTnline 5 column 12
- COLON:line 5 column 13
- IDENTIntegerline 5 column 15
- WHEREwhereline 5 column 23
- IDENTnline 5 column 29
- GE>=line 5 column 31
- INTEGER80line 5 column 34
- NEWLINEline 5 column 36
- INDENT12line 6 column 1
- GIVEgiveline 6 column 13
- TEXT"B"line 6 column 18
- NEWLINEline 6 column 21
- DEDENT8line 7 column 1
- ISisline 7 column 9
- IDENTnline 7 column 12
- COLON:line 7 column 13
- IDENTIntegerline 7 column 15
- WHEREwhereline 7 column 23
- IDENTnline 7 column 29
- GE>=line 7 column 31
- INTEGER70line 7 column 34
- NEWLINEline 7 column 36
- INDENT12line 8 column 1
- GIVEgiveline 8 column 13
- TEXT"C"line 8 column 18
- NEWLINEline 8 column 21
- DEDENT8line 9 column 1
- ISisline 9 column 9
- COLON:line 9 column 12
- IDENTIntegerline 9 column 14
- NEWLINEline 9 column 21
- INDENT12line 10 column 1
- GIVEgiveline 10 column 13
- TEXT"F"line 10 column 18
- NEWLINEline 10 column 21
- DEDENT8line 11 column 1
- OTHERWISEotherwiseline 11 column 9
- NEWLINEline 11 column 18
- INDENT12line 12 column 1
- GIVEgiveline 12 column 13
- TEXT"not a number"line 12 column 18
- NEWLINEline 12 column 32
- DEDENT0line 14 column 1
- DEDENT0line 14 column 1
- DEDENT0line 14 column 1
- PRINTprintline 14 column 1
- IDENTgradeline 14 column 7
- LPAREN(line 14 column 12
- INTEGER95line 14 column 13
- RPAREN)line 14 column 15
- NEWLINEline 14 column 16
- PRINTprintline 15 column 1
- IDENTgradeline 15 column 7
- LPAREN(line 15 column 12
- INTEGER82line 15 column 13
- RPAREN)line 15 column 15
- NEWLINEline 15 column 16
- PRINTprintline 16 column 1
- IDENTgradeline 16 column 7
- LPAREN(line 16 column 12
- INTEGER71line 16 column 13
- RPAREN)line 16 column 15
- NEWLINEline 16 column 16
- PRINTprintline 17 column 1
- IDENTgradeline 17 column 7
- LPAREN(line 17 column 12
- INTEGER50line 17 column 13
- RPAREN)line 17 column 15
- NEWLINEline 17 column 16
- PRINTprintline 18 column 1
- IDENTgradeline 18 column 7
- LPAREN(line 18 column 12
- TEXT"ninety"line 18 column 13
- RPAREN)line 18 column 21
- NEWLINEline 18 column 22
- EOFline 20 column 1
Syntax tree
The venutian ast command shows the grammar the parser found: every statement a node, every name and literal a leaf.- Program
- statements
- FunctionDecl name grade
- params
- Param name score
- body
- ChooseStatement
- subject
- Name identifier score
- branches
- ChooseBranch
- pattern
- TypePattern var_name n type_name Integer
- body
- GiveStatement
- value
- TextLiteral value "A"
- value
- GiveStatement
- guard
- BinaryOp op >=
- left
- Name identifier n
- right
- IntegerLiteral value 90
- left
- BinaryOp op >=
- pattern
- ChooseBranch
- pattern
- TypePattern var_name n type_name Integer
- body
- GiveStatement
- value
- TextLiteral value "B"
- value
- GiveStatement
- guard
- BinaryOp op >=
- left
- Name identifier n
- right
- IntegerLiteral value 80
- left
- BinaryOp op >=
- pattern
- ChooseBranch
- pattern
- TypePattern var_name n type_name Integer
- body
- GiveStatement
- value
- TextLiteral value "C"
- value
- GiveStatement
- guard
- BinaryOp op >=
- left
- Name identifier n
- right
- IntegerLiteral value 70
- left
- BinaryOp op >=
- pattern
- ChooseBranch
- pattern
- TypePattern type_name Integer
- body
- GiveStatement
- value
- TextLiteral value "F"
- value
- GiveStatement
- pattern
- ChooseBranch
- body
- GiveStatement
- value
- TextLiteral value "not a number"
- value
- GiveStatement
- body
- ChooseBranch
- subject
- ChooseStatement
- params
- PrintStatement
- args
- Call
- callee
- Name identifier grade
- args
- Node 0 false
- 1
- IntegerLiteral value 95
- 1
- Node 0 false
- callee
- Call
- args
- PrintStatement
- args
- Call
- callee
- Name identifier grade
- args
- Node 0 false
- 1
- IntegerLiteral value 82
- 1
- Node 0 false
- callee
- Call
- args
- PrintStatement
- args
- Call
- callee
- Name identifier grade
- args
- Node 0 false
- 1
- IntegerLiteral value 71
- 1
- Node 0 false
- callee
- Call
- args
- PrintStatement
- args
- Call
- callee
- Name identifier grade
- args
- Node 0 false
- 1
- IntegerLiteral value 50
- 1
- Node 0 false
- callee
- Call
- args
- PrintStatement
- args
- Call
- callee
- Name identifier grade
- args
- Node 0 false
- 1
- TextLiteral value "ninety"
- 1
- Node 0 false
- callee
- Call
- args
- FunctionDecl name grade
- statements
- Program
Bytecode
The venutian disasm command lists the instructions the virtual machine runs, each operand resolved to the constant it names.main Offset Instruction Operand Constant 0 LOAD_CONST 13 95 1 CALL 1 14 "grade" 2 PRINT 1 3 LOAD_CONST 15 82 4 CALL 1 14 "grade" 5 PRINT 1 6 LOAD_CONST 16 71 7 CALL 1 14 "grade" 8 PRINT 1 9 LOAD_CONST 17 50 10 CALL 1 14 "grade" 11 PRINT 1 12 LOAD_CONST 18 "ninety" 13 CALL 1 14 "grade" 14 PRINT 1 15 HALT function grade(score) Offset Instruction Operand Constant 0 LOAD_NAME 1 "score" 1 STORE_NAME 0 "$choose_subject_1" 2 LOAD_NAME 0 "$choose_subject_1" 3 LOAD_CONST 2 "Integer" 4 CALL 2 3 "is_instance_of" 5 JUMP_IF_FALSE 17 6 LOAD_NAME 0 "$choose_subject_1" 7 STORE_NAME 4 "n" 8 LOAD_NAME 4 "n" 9 LOAD_CONST 5 90 10 GE 11 JUMP_IF_FALSE 16 12 LOAD_CONST 6 "A" 13 RETURN 14 UNBIND_NAME 4 "n" 15 JUMP 56 16 UNBIND_NAME 4 "n" 17 LOAD_NAME 0 "$choose_subject_1" 18 LOAD_CONST 2 "Integer" 19 CALL 2 3 "is_instance_of" 20 JUMP_IF_FALSE 32 21 LOAD_NAME 0 "$choose_subject_1" 22 STORE_NAME 4 "n" 23 LOAD_NAME 4 "n" 24 LOAD_CONST 7 80 25 GE 26 JUMP_IF_FALSE 31 27 LOAD_CONST 8 "B" 28 RETURN 29 UNBIND_NAME 4 "n" 30 JUMP 56 31 UNBIND_NAME 4 "n" 32 LOAD_NAME 0 "$choose_subject_1" 33 LOAD_CONST 2 "Integer" 34 CALL 2 3 "is_instance_of" 35 JUMP_IF_FALSE 47 36 LOAD_NAME 0 "$choose_subject_1" 37 STORE_NAME 4 "n" 38 LOAD_NAME 4 "n" 39 LOAD_CONST 9 70 40 GE 41 JUMP_IF_FALSE 46 42 LOAD_CONST 10 "C" 43 RETURN 44 UNBIND_NAME 4 "n" 45 JUMP 56 46 UNBIND_NAME 4 "n" 47 LOAD_NAME 0 "$choose_subject_1" 48 LOAD_CONST 2 "Integer" 49 CALL 2 3 "is_instance_of" 50 JUMP_IF_FALSE 54 51 LOAD_CONST 11 "F" 52 RETURN 53 JUMP 56 54 LOAD_CONST 12 "not a number" 55 RETURN 56 RETURN_NOTHING Output
The venutian run command compiles the program and runs it on the native virtual machine, and this is what it printed.A B C F not a numberexit 0
concurrency concurrency.ven
Source
The program exactly as it sits in the file, the text the compiler reads.:: 'spawn call_expr' starts a real OS thread running the call right now:: and returns a Task immediately, without waiting. 'await task' blocks:: until it finishes, returning its result, or re-raising its fault.make add(a, b) give a + bt = spawn add(2, 3)print kind(t)print await t:: several tasks make genuine concurrent progressmake slow_double(n) sleep(0.05) give n * 2t1 = spawn slow_double(1)t2 = spawn slow_double(2)t3 = spawn slow_double(3)print await t1print await t2print await t3:: a fault inside a spawned task surfaces at 'await', not silentlymake risky() give 1 / 0failing_task = spawn risky()attempt await failing_taskrescue e print "rescued:", e:: 'share'/'protect': real mutual exclusion across real threadsshare counter = 0make increment_many(count) i = 0 repeat while i < count protect counter counter = counter + 1 i = i + 1tasks = []repeat 8 times tasks = appended(tasks, spawn increment_many(500))repeat for t in tasks await t:: exactly 4000 (8 * 500) every time. 'protect' prevents lost updatesprint counterTokens
The venutian tokens command cuts that text into words, each with its kind, its value, its line and its column.- MAKEmakeline 5 column 1
- IDENTaddline 5 column 6
- LPAREN(line 5 column 9
- IDENTaline 5 column 10
- COMMA,line 5 column 11
- IDENTbline 5 column 13
- RPAREN)line 5 column 14
- NEWLINEline 5 column 15
- INDENT4line 6 column 1
- GIVEgiveline 6 column 5
- IDENTaline 6 column 10
- PLUS+line 6 column 12
- IDENTbline 6 column 14
- NEWLINEline 6 column 15
- DEDENT0line 8 column 1
- IDENTtline 8 column 1
- EQ=line 8 column 3
- SPAWNspawnline 8 column 5
- IDENTaddline 8 column 11
- LPAREN(line 8 column 14
- INTEGER2line 8 column 15
- COMMA,line 8 column 16
- INTEGER3line 8 column 18
- RPAREN)line 8 column 19
- NEWLINEline 8 column 20
- PRINTprintline 9 column 1
- IDENTkindline 9 column 7
- LPAREN(line 9 column 11
- IDENTtline 9 column 12
- RPAREN)line 9 column 13
- NEWLINEline 9 column 14
- PRINTprintline 10 column 1
- AWAITawaitline 10 column 7
- IDENTtline 10 column 13
- NEWLINEline 10 column 14
- MAKEmakeline 13 column 1
- IDENTslow_doubleline 13 column 6
- LPAREN(line 13 column 17
- IDENTnline 13 column 18
- RPAREN)line 13 column 19
- NEWLINEline 13 column 20
- INDENT4line 14 column 1
- IDENTsleepline 14 column 5
- LPAREN(line 14 column 10
- NUMBER0.05line 14 column 11
- RPAREN)line 14 column 15
- NEWLINEline 14 column 16
- GIVEgiveline 15 column 5
- IDENTnline 15 column 10
- STAR*line 15 column 12
- INTEGER2line 15 column 14
- NEWLINEline 15 column 15
- DEDENT0line 17 column 1
- IDENTt1line 17 column 1
- EQ=line 17 column 4
- SPAWNspawnline 17 column 6
- IDENTslow_doubleline 17 column 12
- LPAREN(line 17 column 23
- INTEGER1line 17 column 24
- RPAREN)line 17 column 25
- NEWLINEline 17 column 26
- IDENTt2line 18 column 1
- EQ=line 18 column 4
- SPAWNspawnline 18 column 6
- IDENTslow_doubleline 18 column 12
- LPAREN(line 18 column 23
- INTEGER2line 18 column 24
- RPAREN)line 18 column 25
- NEWLINEline 18 column 26
- IDENTt3line 19 column 1
- EQ=line 19 column 4
- SPAWNspawnline 19 column 6
- IDENTslow_doubleline 19 column 12
- LPAREN(line 19 column 23
- INTEGER3line 19 column 24
- RPAREN)line 19 column 25
- NEWLINEline 19 column 26
- PRINTprintline 20 column 1
- AWAITawaitline 20 column 7
- IDENTt1line 20 column 13
- NEWLINEline 20 column 15
- PRINTprintline 21 column 1
- AWAITawaitline 21 column 7
- IDENTt2line 21 column 13
- NEWLINEline 21 column 15
- PRINTprintline 22 column 1
- AWAITawaitline 22 column 7
- IDENTt3line 22 column 13
- NEWLINEline 22 column 15
- MAKEmakeline 25 column 1
- IDENTriskyline 25 column 6
- LPAREN(line 25 column 11
- RPAREN)line 25 column 12
- NEWLINEline 25 column 13
- INDENT4line 26 column 1
- GIVEgiveline 26 column 5
- INTEGER1line 26 column 10
- SLASH/line 26 column 12
- INTEGER0line 26 column 14
- NEWLINEline 26 column 15
- DEDENT0line 28 column 1
- IDENTfailing_taskline 28 column 1
- EQ=line 28 column 14
- SPAWNspawnline 28 column 16
- IDENTriskyline 28 column 22
- LPAREN(line 28 column 27
- RPAREN)line 28 column 28
- NEWLINEline 28 column 29
- ATTEMPTattemptline 29 column 1
- NEWLINEline 29 column 8
- INDENT4line 30 column 1
- AWAITawaitline 30 column 5
- IDENTfailing_taskline 30 column 11
- NEWLINEline 30 column 23
- DEDENT0line 31 column 1
- RESCUErescueline 31 column 1
- IDENTeline 31 column 8
- NEWLINEline 31 column 9
- INDENT4line 32 column 1
- PRINTprintline 32 column 5
- TEXT"rescued:"line 32 column 11
- COMMA,line 32 column 21
- IDENTeline 32 column 23
- NEWLINEline 32 column 24
- DEDENT0line 35 column 1
- SHAREshareline 35 column 1
- IDENTcounterline 35 column 7
- EQ=line 35 column 15
- INTEGER0line 35 column 17
- NEWLINEline 35 column 18
- MAKEmakeline 37 column 1
- IDENTincrement_manyline 37 column 6
- LPAREN(line 37 column 20
- IDENTcountline 37 column 21
- RPAREN)line 37 column 26
- NEWLINEline 37 column 27
- INDENT4line 38 column 1
- IDENTiline 38 column 5
- EQ=line 38 column 7
- INTEGER0line 38 column 9
- NEWLINEline 38 column 10
- REPEATrepeatline 39 column 5
- WHILEwhileline 39 column 12
- IDENTiline 39 column 18
- LT<line 39 column 20
- IDENTcountline 39 column 22
- NEWLINEline 39 column 27
- INDENT8line 40 column 1
- PROTECTprotectline 40 column 9
- IDENTcounterline 40 column 17
- NEWLINEline 40 column 24
- INDENT12line 41 column 1
- IDENTcounterline 41 column 13
- EQ=line 41 column 21
- IDENTcounterline 41 column 23
- PLUS+line 41 column 31
- INTEGER1line 41 column 33
- NEWLINEline 41 column 34
- DEDENT8line 42 column 1
- IDENTiline 42 column 9
- EQ=line 42 column 11
- IDENTiline 42 column 13
- PLUS+line 42 column 15
- INTEGER1line 42 column 17
- NEWLINEline 42 column 18
- DEDENT0line 44 column 1
- DEDENT0line 44 column 1
- IDENTtasksline 44 column 1
- EQ=line 44 column 7
- LBRACKET[line 44 column 9
- RBRACKET]line 44 column 10
- NEWLINEline 44 column 11
- REPEATrepeatline 45 column 1
- INTEGER8line 45 column 8
- TIMEStimesline 45 column 10
- NEWLINEline 45 column 15
- INDENT4line 46 column 1
- IDENTtasksline 46 column 5
- EQ=line 46 column 11
- IDENTappendedline 46 column 13
- LPAREN(line 46 column 21
- IDENTtasksline 46 column 22
- COMMA,line 46 column 27
- SPAWNspawnline 46 column 29
- IDENTincrement_manyline 46 column 35
- LPAREN(line 46 column 49
- INTEGER500line 46 column 50
- RPAREN)line 46 column 53
- RPAREN)line 46 column 54
- NEWLINEline 46 column 55
- DEDENT0line 48 column 1
- REPEATrepeatline 48 column 1
- FORforline 48 column 8
- IDENTtline 48 column 12
- INinline 48 column 14
- IDENTtasksline 48 column 17
- NEWLINEline 48 column 22
- INDENT4line 49 column 1
- AWAITawaitline 49 column 5
- IDENTtline 49 column 11
- NEWLINEline 49 column 12
- DEDENT0line 52 column 1
- PRINTprintline 52 column 1
- IDENTcounterline 52 column 7
- NEWLINEline 52 column 14
- EOFline 54 column 1
Syntax tree
The venutian ast command shows the grammar the parser found: every statement a node, every name and literal a leaf.- Program
- statements
- FunctionDecl name add
- params
- Param name a
- Param name b
- body
- GiveStatement
- value
- BinaryOp op +
- left
- Name identifier a
- right
- Name identifier b
- left
- BinaryOp op +
- value
- GiveStatement
- params
- AssignStatement
- target
- Name identifier t
- value
- SpawnExpr
- call
- Call
- callee
- Name identifier add
- args
- Node 0 false
- 1
- IntegerLiteral value 2
- 1
- Node 0 false
- 1
- IntegerLiteral value 3
- 1
- Node 0 false
- callee
- Call
- call
- SpawnExpr
- target
- PrintStatement
- args
- Call
- callee
- Name identifier kind
- args
- Node 0 false
- 1
- Name identifier t
- 1
- Node 0 false
- callee
- Call
- args
- PrintStatement
- args
- AwaitExpr
- task
- Name identifier t
- task
- AwaitExpr
- args
- FunctionDecl name slow_double
- params
- Param name n
- body
- ExprStatement
- expr
- Call
- callee
- Name identifier sleep
- args
- Node 0 false
- 1
- NumberLiteral value 0.05
- 1
- Node 0 false
- callee
- Call
- expr
- GiveStatement
- value
- BinaryOp op *
- left
- Name identifier n
- right
- IntegerLiteral value 2
- left
- BinaryOp op *
- value
- ExprStatement
- params
- AssignStatement
- target
- Name identifier t1
- value
- SpawnExpr
- call
- Call
- callee
- Name identifier slow_double
- args
- Node 0 false
- 1
- IntegerLiteral value 1
- 1
- Node 0 false
- callee
- Call
- call
- SpawnExpr
- target
- AssignStatement
- target
- Name identifier t2
- value
- SpawnExpr
- call
- Call
- callee
- Name identifier slow_double
- args
- Node 0 false
- 1
- IntegerLiteral value 2
- 1
- Node 0 false
- callee
- Call
- call
- SpawnExpr
- target
- AssignStatement
- target
- Name identifier t3
- value
- SpawnExpr
- call
- Call
- callee
- Name identifier slow_double
- args
- Node 0 false
- 1
- IntegerLiteral value 3
- 1
- Node 0 false
- callee
- Call
- call
- SpawnExpr
- target
- PrintStatement
- args
- AwaitExpr
- task
- Name identifier t1
- task
- AwaitExpr
- args
- PrintStatement
- args
- AwaitExpr
- task
- Name identifier t2
- task
- AwaitExpr
- args
- PrintStatement
- args
- AwaitExpr
- task
- Name identifier t3
- task
- AwaitExpr
- args
- FunctionDecl name risky
- body
- GiveStatement
- value
- BinaryOp op /
- left
- IntegerLiteral value 1
- right
- IntegerLiteral value 0
- left
- BinaryOp op /
- value
- GiveStatement
- body
- AssignStatement
- target
- Name identifier failing_task
- value
- SpawnExpr
- call
- Call
- callee
- Name identifier risky
- callee
- Call
- call
- SpawnExpr
- target
- AttemptStatement
- body
- ExprStatement
- expr
- AwaitExpr
- task
- Name identifier failing_task
- task
- AwaitExpr
- expr
- ExprStatement
- rescues
- RescueClause var_name e
- body
- PrintStatement
- args
- TextLiteral value "rescued:"
- Name identifier e
- args
- PrintStatement
- body
- RescueClause var_name e
- body
- ShareStatement name counter
- value
- IntegerLiteral value 0
- value
- FunctionDecl name increment_many effects "Concurrency"
- params
- Param name count
- body
- AssignStatement
- target
- Name identifier i
- value
- IntegerLiteral value 0
- target
- RepeatStatement
- form
- RepeatWhile
- condition
- BinaryOp op <
- left
- Name identifier i
- right
- Name identifier count
- left
- BinaryOp op <
- condition
- RepeatWhile
- body
- ProtectStatement name counter
- body
- AssignStatement
- target
- Name identifier counter
- value
- BinaryOp op +
- left
- Name identifier counter
- right
- IntegerLiteral value 1
- left
- BinaryOp op +
- target
- AssignStatement
- body
- AssignStatement
- target
- Name identifier i
- value
- BinaryOp op +
- left
- Name identifier i
- right
- IntegerLiteral value 1
- left
- BinaryOp op +
- target
- ProtectStatement name counter
- form
- AssignStatement
- params
- AssignStatement
- target
- Name identifier tasks
- value
- ListLiteral
- target
- RepeatStatement
- form
- RepeatTimes
- count
- IntegerLiteral value 8
- count
- RepeatTimes
- body
- AssignStatement
- target
- Name identifier tasks
- value
- Call
- callee
- Name identifier appended
- args
- Node 0 false
- 1
- Name identifier tasks
- 1
- Node 0 false
- 1
- SpawnExpr
- call
- Call
- callee
- Name identifier increment_many
- args
- Node 0 false
- 1
- IntegerLiteral value 500
- 1
- Node 0 false
- callee
- Call
- call
- SpawnExpr
- 1
- Node 0 false
- callee
- Call
- target
- AssignStatement
- form
- RepeatStatement
- form
- RepeatFor loop_var "t"
- iterable
- Name identifier tasks
- iterable
- RepeatFor loop_var "t"
- body
- ExprStatement
- expr
- AwaitExpr
- task
- Name identifier t
- task
- AwaitExpr
- expr
- ExprStatement
- form
- PrintStatement
- args
- Name identifier counter
- args
- FunctionDecl name add
- statements
- Program
Bytecode
The venutian disasm command lists the instructions the virtual machine runs, each operand resolved to the constant it names.main Offset Instruction Operand Constant 0 LOAD_NAME 13 "add" 1 BUILD_LIST 0 2 LOAD_CONST 5 2 3 LIST_APPEND 4 LOAD_CONST 14 3 5 LIST_APPEND 6 CALL 0 15 "new_map" 7 SPAWN 8 STORE_NAME 16 "t" 9 LOAD_NAME 16 "t" 10 CALL 1 17 "kind" 11 PRINT 1 12 LOAD_NAME 16 "t" 13 AWAIT 14 PRINT 1 15 LOAD_NAME 18 "slow_double" 16 BUILD_LIST 0 17 LOAD_CONST 6 1 18 LIST_APPEND 19 CALL 0 15 "new_map" 20 SPAWN 21 STORE_NAME 19 "t1" 22 LOAD_NAME 18 "slow_double" 23 BUILD_LIST 0 24 LOAD_CONST 5 2 25 LIST_APPEND 26 CALL 0 15 "new_map" 27 SPAWN 28 STORE_NAME 20 "t2" 29 LOAD_NAME 18 "slow_double" 30 BUILD_LIST 0 31 LOAD_CONST 14 3 32 LIST_APPEND 33 CALL 0 15 "new_map" 34 SPAWN 35 STORE_NAME 21 "t3" 36 LOAD_NAME 19 "t1" 37 AWAIT 38 PRINT 1 39 LOAD_NAME 20 "t2" 40 AWAIT 41 PRINT 1 42 LOAD_NAME 21 "t3" 43 AWAIT 44 PRINT 1 45 LOAD_NAME 22 "risky" 46 BUILD_LIST 0 47 CALL 0 15 "new_map" 48 SPAWN 49 STORE_NAME 23 "failing_task" 50 ENTER_ATTEMPT 24 51 LOAD_NAME 23 "failing_task" 52 AWAIT 53 POP 54 EXIT_ATTEMPT 55 JUMP 60 56 LOAD_CONST 25 "rescued:" 57 LOAD_NAME 26 "e" 58 PRINT 2 59 JUMP 60 60 LOAD_CONST 7 0 61 MAKE_SHARED 62 STORE_NAME 10 "counter" 63 BUILD_LIST 0 64 STORE_NAME 27 "tasks" 65 LOAD_CONST 30 8 66 STORE_NAME 28 "$rt_len_3" 67 LOAD_CONST 7 0 68 STORE_NAME 29 "$rt_idx_3" 69 LOAD_NAME 29 "$rt_idx_3" 70 LOAD_NAME 28 "$rt_len_3" 71 LT 72 JUMP_IF_FALSE 87 73 LOAD_NAME 27 "tasks" 74 LOAD_NAME 31 "increment_many" 75 BUILD_LIST 0 76 LOAD_CONST 32 500 77 LIST_APPEND 78 CALL 0 15 "new_map" 79 SPAWN 80 CALL 2 33 "appended" 81 STORE_NAME 27 "tasks" 82 LOAD_NAME 29 "$rt_idx_3" 83 LOAD_CONST 6 1 84 ADD 85 STORE_NAME 29 "$rt_idx_3" 86 JUMP 69 87 LOAD_NAME 27 "tasks" 88 STORE_NAME 34 "$rf_src_4" 89 LOAD_NAME 34 "$rf_src_4" 90 CALL 1 36 "$is_generator" 91 JUMP_IF_FALSE 102 92 LOAD_NAME 34 "$rf_src_4" 93 CALL 1 37 "$has_next" 94 JUMP_IF_FALSE 121 95 LOAD_NAME 34 "$rf_src_4" 96 CALL 1 38 "$next_value" 97 STORE_NAME 16 "t" 98 LOAD_NAME 16 "t" 99 AWAIT 100 POP 101 JUMP 92 102 LOAD_CONST 7 0 103 STORE_NAME 35 "$rf_idx_4" 104 LOAD_NAME 35 "$rf_idx_4" 105 LOAD_NAME 34 "$rf_src_4" 106 LEN 107 LT 108 JUMP_IF_FALSE 121 109 LOAD_NAME 34 "$rf_src_4" 110 LOAD_NAME 35 "$rf_idx_4" 111 INDEX 112 STORE_NAME 16 "t" 113 LOAD_NAME 16 "t" 114 AWAIT 115 POP 116 LOAD_NAME 35 "$rf_idx_4" 117 LOAD_CONST 6 1 118 ADD 119 STORE_NAME 35 "$rf_idx_4" 120 JUMP 104 121 LOAD_NAME 10 "counter" 122 PRINT 1 123 HALT function add(a, b) Offset Instruction Operand Constant 0 LOAD_NAME 0 "a" 1 LOAD_NAME 1 "b" 2 ADD 3 RETURN 4 RETURN_NOTHING function slow_double(n) Offset Instruction Operand Constant 0 LOAD_CONST 2 0.05 1 CALL 1 3 "sleep" 2 POP 3 LOAD_NAME 4 "n" 4 LOAD_CONST 5 2 5 MUL 6 RETURN 7 RETURN_NOTHING function risky() Offset Instruction Operand Constant 0 LOAD_CONST 6 1 1 LOAD_CONST 7 0 2 DIV 3 RETURN 4 RETURN_NOTHING function increment_many(count) Offset Instruction Operand Constant 0 LOAD_CONST 7 0 1 STORE_NAME 8 "i" 2 LOAD_NAME 8 "i" 3 LOAD_NAME 9 "count" 4 LT 5 JUMP_IF_FALSE 23 6 PROTECT_ENTER 10 "counter" 7 ENTER_ATTEMPT 11 8 LOAD_NAME 10 "counter" 9 LOAD_CONST 6 1 10 ADD 11 STORE_NAME 10 "counter" 12 EXIT_ATTEMPT 13 PROTECT_EXIT 10 "counter" 14 JUMP 18 15 PROTECT_EXIT 10 "counter" 16 LOAD_NAME 12 "$protect_exc_2" 17 RAISE 18 LOAD_NAME 8 "i" 19 LOAD_CONST 6 1 20 ADD 21 STORE_NAME 8 "i" 22 JUMP 2 23 RETURN_NOTHING Output
The venutian run command compiles the program and runs it on the native virtual machine, and this is what it printed.Task 5 2 4 6 rescued: Division by zero. 4000exit 0
The playground
Nine real programs, each with its recorded output and timing. Run compiles a program with Venutian's self hosted compiler and executes it on the native virtual machine, compiled to WebAssembly and running in your browser.
-
hello.ven print "Hello from Venutian"Output of hello.ven Hello from Venutian -
guards.ven make grade(score) choose score is n: Integer where n >= 90 give "A" is n: Integer where n >= 80 give "B" is n: Integer where n >= 70 give "C" is : Integer give "F" otherwise give "not a number" print grade(95) print grade(82) print grade(71) print grade(50) print grade("ninety")Output of guards.ven A B C F not a number -
concurrency.ven :: 'spawn call_expr' starts a real OS thread running the call right now :: and returns a Task immediately, without waiting. 'await task' blocks :: until it finishes, returning its result, or re-raising its fault. make add(a, b) give a + b t = spawn add(2, 3) print kind(t) print await t :: several tasks make genuine concurrent progress make slow_double(n) sleep(0.05) give n * 2 t1 = spawn slow_double(1) t2 = spawn slow_double(2) t3 = spawn slow_double(3) print await t1 print await t2 print await t3 :: a fault inside a spawned task surfaces at 'await', not silently make risky() give 1 / 0 failing_task = spawn risky() attempt await failing_task rescue e print "rescued:", e :: 'share'/'protect': real mutual exclusion across real threads share counter = 0 make increment_many(count) i = 0 repeat while i < count protect counter counter = counter + 1 i = i + 1 tasks = [] repeat 8 times tasks = appended(tasks, spawn increment_many(500)) repeat for t in tasks await t :: exactly 4000 (8 * 500) every time. 'protect' prevents lost updates print counterOutput of concurrency.ven Task 5 2 4 6 rescued: Division by zero. 4000
Run it on your own machine.
macOS, Apple silicon
curl -fsSL https://venutian.org/install.sh | sh
Linux
x86_64 and arm64. Ubuntu, Debian, Fedora, Alpine and friends.
curl -fsSL https://venutian.org/install.sh | sh
Windows
irm https://venutian.org/install.ps1 | iex
powershell -c "irm https://venutian.org/install.ps1 | iex"
Run this on your Mac.
For Macs with Apple silicon.
curl -fsSL https://venutian.org/install.sh | sh
x86_64 and arm64. Ubuntu, Debian, Fedora, Alpine and friends.
curl -fsSL https://venutian.org/install.sh | sh
irm https://venutian.org/install.ps1 | iex
powershell -c "irm https://venutian.org/install.ps1 | iex"
Self hosting in five stages
Venutian's own compiler pipeline is written in Venutian, one stage at a time, each stage checked against the reference implementation before the next one starts.
Tokenizer
A real tokenizer for a small expression language, written entirely in Venutian (
examples/).self_hosting_lexer.ven Lexer port
A line for line port of the production lexer, checked token by token against the reference lexer over the whole example corpus.
Parser and checker
Ports of the production parser and semantic analyzer, checked by AST equality and accept and reject tests.
Code generator
A port of the production code generator (1,133 lines of Venutian) plus the VBC serializer, so the whole pipeline runs in Venutian and emits a loadable
.vbcfile.Native VM
A from scratch native virtual machine with no third party libraries. From here, new programs compile and run with nothing but Venutian in the loop.
Native ahead of time compilation
venutian build --native compiles ahead of time with the same compiler and binary that produced every number on the performance page. Two decisions do the work: the recursive body of a hot function is inlined once, and a frameless base case skips building a stack frame for the branch that just returns.
On fib(30) the result runs 43.6 million instructions against clang's 45.5 million on the same round: 1.000x the cycles of clang -O2 and 0.985x the wall time, from a compiler written in Venutian.
$ venutian build --native hello.ven
n3: wrote hello bytes=33440 words=2253 functions=1
$ ./hello
Hello from Venutian