Skip to content

Commit f5a1264

Browse files
Merge pull request #77 from adam-mcdaniel/modules
Module system📦 New parser📝 Sage Lisp Preprocessor🛸
2 parents 485af80 + b5f9afc commit f5a1264

File tree

273 files changed

+52884
-21944
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

273 files changed

+52884
-21944
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,6 @@ massif.out.*
1010
/*.txt
1111
/*.sg
1212
/benches/temp
13-
/benches/temp.c
13+
/benches/temp.c
14+
.DS_Store
15+
ffi.h

CHANGELOG.md

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,113 @@ New VM instructions:
7676

7777
### Fixed
7878

79-
Generated code size is now up to 7x smaller than before.
79+
Generated code size is now up to 7x smaller than before.
80+
81+
## [0.1.0-alpha] - 2024-9-4
82+
83+
Sage has just gotten a major upgrade, with a new module system📦 parser📝 and the Sage Lisp Preprocessor🛸!!!
84+
85+
### Added
86+
87+
- [Sage lisp compile time preprocessor language](https://github.com/adam-mcdaniel/sage-lisp)
88+
```rs
89+
// Define some code that modifies the AST of the expression it's called on
90+
#![(defun square_sage_const(x) {
91+
// Get a constant integer
92+
(define n x@"ConstExpr"@"Int")
93+
// Return the constant integer squared
94+
["ConstExpr" ["Float" n * n]]
95+
})]
96+
97+
// Call the compile time macro on 5.
98+
// This will cause the compiler to perceive this code as `println(25)`
99+
println(#[square_sage_const] 5);
100+
```
101+
102+
- Module system
103+
104+
```rs
105+
// Import a module from a file named `from_file.sg`
106+
mod from_file;
107+
108+
// Define a module `io` with `getchar`
109+
mod io {
110+
fun getchar(): Char {
111+
let mut ch = '\0';
112+
input(&mut ch);
113+
return ch;
114+
}
115+
}
116+
117+
// A module to test importing from other modules
118+
mod testing {
119+
mod internals {
120+
// Import getchar from two modules up
121+
from io import getchar;
122+
123+
// Use it in a function
124+
fun get_two(): (Char, Char) { (getchar(), getchar()) }
125+
}
126+
127+
// Get two chars and print them
128+
fun get_two_then_print() {
129+
// Import from a submodule, which imports from a supermodule
130+
from internals import get_two;
131+
let (a, b) = get_two();
132+
print(a, b);
133+
}
134+
}
135+
136+
from testing import get_two_then_print;
137+
get_two_then_print();
138+
139+
// Get two values and print them
140+
for let mut i=0; i<6; i+=1; {
141+
// We can also use the full path name
142+
testing.get_two_then_print();
143+
}
144+
```
145+
146+
- Standard library
147+
148+
```rs
149+
from std.fallible import Option, Result;
150+
151+
enum Error {
152+
DivideByZero { numerator: Int },
153+
Custom(&Char)
154+
}
155+
156+
fun divide(n: Int, d: Int): Option<Int> {
157+
match d {
158+
0 => Option<Int> of Nothing,
159+
_ => Option<Int> of Some(n / d)
160+
}
161+
}
162+
163+
164+
fun main(): Result<(), Error> {
165+
println(divide(5, 2));
166+
println(divide(5, 0));
167+
168+
return Result<(), Error> of Ok(());
169+
}
170+
171+
println(main());
172+
```
173+
174+
- Better constant evaluation
175+
- `from module.submodule import x, y as alias_for_y;` import statements
176+
- `from module.submodule import *` import statements
177+
178+
### Changed
179+
180+
- The `def` keyword has been changed in favor of `fun`.
181+
- `for` loops now have an extra semicolon on the last statement. `i += 1 {` becomes `i += 1; {`.
182+
183+
### Fixed
184+
185+
The compiler is significantly faster -- about 20 times faster at compiling the AES example.
186+
This is mainly due to the much faster parser implemented with Nom instead of Pest.
187+
There are also several optimizations with constant evaluation I added, along with optimizations
188+
for how declarations are typechecked.

Cargo.toml

Lines changed: 70 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,91 @@
1+
###############################################################################
2+
# THE SAGE PROGRAMMING LANGUAGE #
3+
# #
4+
# █████ ██████ ███████ ██████ `-. _.-' #
5+
# ███░░ ░░░░░███ ███░░███ ███░░███ \ `, .'/.' #
6+
# ░░█████ ███████ ░███ ░███░███████ \`.`. :.-'.-= .-'/ #
7+
# ░░░░███ ███░░███ ░███ ░███░███░░░ `-.:/o .'-'/ .' #
8+
# ██████ ░░████████░░███████░░██████ o\o / ._/.' #
9+
# ░░░░░░ ░░░░░░░░ ░░░░░███ ░░░░░░ \| /o|\`. #
10+
# ███ ░███ |'o `.`.'. #
11+
# ░░██████ `--' #
12+
# ░░░░░░ #
13+
# #
14+
###############################################################################
115
[package]
216
name = "sage"
317
authors = ["Adam McDaniel <[email protected]> (https://adam-mcdaniel.net)"]
4-
version = "0.0.4-alpha"
18+
version = "0.1.0-alpha"
519
edition = "2021"
620
license = "MIT"
721
description = "A portable programming language with a compact backend"
822
readme = "README.md"
923

10-
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
11-
[lib]
12-
bench = false
13-
24+
###############################################################################
25+
## BINARIES
26+
###############################################################################
1427
[[bin]]
1528
name = "sage"
1629
path = "src/cli.rs"
1730
bench = false
1831

32+
###############################################################################
33+
## DEPENDENCIES
34+
###############################################################################
1935
[dependencies]
20-
regex = { version = "1.8.1", features = ["unicode"] }
21-
maplit = "1.0.2"
22-
lazy_static = "1.4.0"
23-
lalrpop-util = "0.19.8"
24-
lalrpop = { version = "=0.19.9", features = ["lexer"] }
25-
clap = { version ="4.2.4", features = ["derive", "cargo"] }
26-
no-comment = "0.0.3"
27-
pest = "2.6.0"
28-
pest_derive = "2.6.0"
29-
snailquote = "0.3.1"
30-
codespan-reporting = "0.11.1"
31-
log = {version = "0.4.20", features = ["release_max_level_info"] }
32-
env_logger = "0.10.0"
33-
rayon = "1.9.0"
36+
#######################################
37+
## QUALITY OF LIFE / MACROS
38+
#######################################
39+
maplit = "1.0"
40+
lazy_static = "1.5"
41+
nom = "7.1"
42+
43+
#######################################
44+
## THREADING / PARALLELISM
45+
#######################################
46+
rayon = "1.10"
47+
48+
#######################################
49+
## ERROR REPORTING
50+
#######################################
51+
codespan-reporting = "0.11"
52+
log = {version = "0.4", features = ["release_max_level_error"] }
53+
env_logger = "0.11"
54+
55+
#######################################
56+
## SAGE LISP PREPROCESSING
57+
#######################################
58+
serde = { version = "1.0", features = ["rc"] }
59+
serde_derive = "1.0"
60+
sage-lisp = { git = "https://github.com/adam-mcdaniel/sage-lisp" }
3461

35-
[dev-dependencies]
36-
criterion = "0.5"
3762

38-
# Add a build-time dependency on the lalrpop library:
63+
#######################################
64+
## PARSING
65+
#######################################
66+
lalrpop-util = { version = "0.21", features = ["lexer"] }
67+
regex = { version = "1.10", features = ["unicode"] }
68+
clap = { version ="4.5", features = ["derive", "cargo"] }
69+
no-comment = "0.0.3"
70+
snailquote = "0.3"
71+
3972
[build-dependencies]
40-
regex = { version = "1.8.1", features = ["unicode"] }
41-
lalrpop = { version = "=0.19.9", features = ["lexer"] }
73+
regex = { version = "1.10", features = ["unicode"] }
74+
lalrpop = "0.21"
75+
76+
###############################################################################
77+
## PROFILING
78+
###############################################################################
79+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
80+
[lib]
81+
bench = false
4282

4383
[[bench]]
4484
name = "frontend"
4585
harness = false
86+
87+
[dev-dependencies]
88+
criterion = "0.5"
89+
90+
[profile.release]
91+
debug = true

0 commit comments

Comments
 (0)