summaryrefslogtreecommitdiff
path: root/doc/demo.txt
blob: 58c0839ec41505b645b6cda4d1d9948d264ffe5e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
type vec2 = [2]f32

type Sprite = enum u8 {
	BLANK,
	PLAYER
}

type Player = struct {
	pos, vel vec2
}

extern {
	blit proc(spr Sprite, x, y i32),
	exp func(v f32) f32
}

proc frame(dt f32) {
	/* unary .. can splat an array as parameters */
	blit(.PLAYER, ..plr.pos)
	plr.pos += plr.vel * dt
	plr.vel *= exp(-dt * 5)
}

/* statements

 type Ident = T			Alias Ident to type T
 extern Ident T			Define an external variable (or function!) of the given type
 extern { a A, b B... }		Block of extern declarations, formatted like a struct

*/

/* expressions

 N				Integer
 N.N | NeN | N.NeN		Float
 [-+~] A			Unary operator on term A
 A [+-/*%&|^] B			Binary operator on term A and expression B
 A := B				Type inference assignment
 A, B, C := D			
 T { ... }			Literal of type T; mostly only makes sense for structs,
 				but this can be used to do something like u8 { 2 } too.

/* types

 IDENT		       		type of the given identifier
 ^T		       		pointer to type T
 enum { FOO, BAR... }  		enum
 enum T { FOO, BAR... }  	enum with backing type T, which must be an integer type
 struct { a A, b B... }		struct
 A..B				range (kinda an anonymous enum)
 				A and B must be ordinal types (enum value, integer, or character)
 [N]T				array of T of length N
 [E]T				array of T indexed by enum or range E
 []T				slice
 (Ta, Tb...)			tuple of given types; can be destructured to multiple assignment
 set[E]				a set of enum or range E
 proc(a A, b B...)		function pointer
 func(a A, b B...) T 		function pointer with return value T

*/

Expr = LValue | Literal
LValue = Ident | LValue '.' Ident
Literal = Number
Number = Integer | Float
Integer = /[0-9]+/
Float = Integer 'e' Integer | Integer '.' Integer | Integer '.' Integer 'e' Integer

 IDENT				Variable
 LVALUE . IDENT			Member access
 [0-9]+				Integer
 [0-9]+ . [0-9]+		Float
 [0-9]+ . [0-9]+ e [0-9]+	Float
 F(E1, E2...)			function call with the given expression arguments

*/

/* import first tries to scan local directory for the package, then standard
 * system directory; in said directory it will look for an IR cache file,
 * or compile a new one if it's not present (or if its last-modified time
 * is older than the compiler executable), which is imported with a name
 * equivalent to the last part of the path.
 *
 * codegen is only performed on procedures that get called from main and their
 * own dependencies, recursively.  this allows to keep output binaries small.
 * maybe supply some sort of export qualifier to do something similar for
 * procedures that aren't main.
 */

import "io"

proc main {
	io.print("Hello, world!")
}