This repository has been archived by the owner on Jun 6, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
prismo.rc
128 lines (104 loc) · 3.34 KB
/
prismo.rc
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#[link(name = "prismo",
vers = "0.0",
uuid = "c39c6bb9-51bf-4649-827d-7c384de60845",
url = "https://github.com/rfw/prismo")];
#[comment = "The Prismo programming language."];
#[license = "MIT"];
extern mod core;
extern mod std;
use core::at_vec;
use core::os;
use core::path;
use std::getopts;
pub mod ast;
pub mod lexer;
pub mod parser;
pub mod interp {
pub mod aster;
pub mod env;
pub mod types;
}
fn print_usage(program: &str) {
io::println(fmt!("Usage: %s [options...] FILE [args...]", program));
}
fn print_help(program: &str) {
print_usage(program);
io::println("");
io::println(" -t, --tokens Dump token stream.");
io::println(" -a, --ast Dump AST.");
io::println(" -e, --env Dump root environment at the end of execution.");
io::println(" -h, --help Print this message.");
}
fn main() {
let args = os::args();
let program = copy args[0];
let options: &[~str];
let filename: ~str;
let argv: &[~str];
match vec::position(vec::tail(args), {|t|
t.char_at(0) != '-' && t.len() > 1
}) {
option::None => {
print_usage(program);
fail!(~"file to run not specified")
},
option::Some(i) => {
options = vec::slice(args, 1, i + 1);
filename = copy args[i + 1];
argv = vec::slice(args, i, vec::len(args));
}
}
let opts = ~[
getopts::optflag("t"), getopts::optflag("tokens"),
getopts::optflag("a"), getopts::optflag("ast"),
getopts::optflag("e"), getopts::optflag("env"),
getopts::optflag("h"), getopts::optflag("help")
];
let matches = match getopts::getopts(options, opts) {
result::Ok(m) => m,
result::Err(f) => {
print_usage(program);
fail!(getopts::fail_str(f))
}
};
if getopts::opt_present(&matches, "h") || getopts::opt_present(&matches, "help") {
print_help(program);
return;
}
let mut import_paths = @[];
let (filename, r) = if filename == ~"-" {
import_paths += @[os::getcwd()];
(@"<stdin>", io::stdin())
} else {
let path = os::make_absolute(&path::Path(filename));
import_paths += @[path.dir_path()];
match io::file_reader(&path) {
result::Ok(r) => (path.to_str().to_managed(), r),
result::Err(f) => fail!(f)
}
};
for os::env().each |&(k, v)| {
if k == ~"PRISMO_PATH" {
import_paths += @[path::Path(v)];
}
}
let tokens = lexer::lex(r);
if getopts::opt_present(&matches, "t") || getopts::opt_present(&matches, "tokens") {
io::println(fmt!("%?", tokens));
}
let program = parser::parse(tokens);
if getopts::opt_present(&matches, "a") || getopts::opt_present(&matches, "ast") {
io::println(fmt!("%?", program));
}
let interp = @mut interp::aster::Interp::new(import_paths, at_vec::from_slice(do argv.map |arg| {
arg.to_managed()
}));
interp::aster::run(interp, filename, program);
if getopts::opt_present(&matches, "e") || getopts::opt_present(&matches, "env") {
io::println("ENV");
for interp.root.vars.mutate_values |k, v| {
io::println(fmt!("%s: %s", **k, interp::types::repr(*v)));
}
io::println("END OF ENV");
}
}