Skip to content

Commit 43bd85f

Browse files
Chore: Convert VmErr type/value/runtime variants to &'static str (optimization of binary size).
1 parent 0eec61e commit 43bd85f

8 files changed

Lines changed: 113 additions & 111 deletions

File tree

compiler/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use log::{debug, info, error};
44

55
fn parse_args() -> (String, usize, bool, bool) {
66
let args: Vec<_> = env::args().skip(1).collect();
7-
if args.is_empty() || args.contains(&"-h".into()) {
7+
if args.is_empty() || args.iter().any(|a| a == "-h") {
88
println!("edge [-c code] [-d] [-dd] [-q] [--sandbox] <file>");
99
exit(0);
1010
}
@@ -17,7 +17,7 @@ fn parse_args() -> (String, usize, bool, bool) {
1717
exit(1);
1818
});
1919
let v = args.iter().filter(|&a| a == "-d").count() + (args.iter().filter(|&a| a == "-dd").count() * 2);
20-
(p, if v > 0 { v + 2 } else { 0 }, args.contains(&"-q".into()), args.contains(&"--sandbox".into()))
20+
(p, if v > 0 { v + 2 } else { 0 }, args.iter().any(|a| a == "-q"), args.iter().any(|a| a == "--sandbox"))
2121
}
2222

2323
fn run(path: &str, _q: bool, sandbox: bool) -> Result<(), String> {

compiler/src/modules/parser/mod.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub struct Parser<'src, I: Iterator<Item = Token>> {
2727
pub(super) ssa_versions: HashMap<String, u32>,
2828
pub(super) join_stack: Vec<JoinNode>,
2929
pub(super) loop_starts: Vec<u16>,
30+
pub(super) last_line: usize,
3031
pub(super) loop_breaks: Vec<Vec<usize>>,
3132
pub(super) expr_depth: usize,
3233
pub(super) saw_newline: bool,
@@ -152,20 +153,20 @@ Token Helpers
152153

153154
impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
154155
pub(super) fn advance(&mut self) -> Token {
155-
self.tokens.next().unwrap_or(Token {
156+
let tok = self.tokens.next().unwrap_or(Token {
156157
kind: TokenType::Endmarker,
157-
line: 0,
158-
start: 0,
159-
end: 0,
160-
})
158+
line: 0, start: 0, end: 0,
159+
});
160+
self.last_line = tok.line;
161+
tok
161162
}
162163

163164
pub(super) fn error(&mut self, msg: &str) {
164165
let (line, col, end) = self
165166
.tokens
166167
.peek()
167168
.map(|t| (t.line, t.start, t.end))
168-
.unwrap_or((0, 0, 0));
169+
.unwrap_or((self.last_line, 0, 0));
169170
self.errors.push(Diagnostic { line, col, end, msg: msg.to_string() });
170171

171172
// Sync to next statement boundary to suppress cascading false positives.
@@ -241,6 +242,7 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
241242
loop_breaks: Vec::new(),
242243
saw_newline: false,
243244
expr_depth: 0,
245+
last_line: 0,
244246
errors: Vec::new(),
245247
}
246248
}
@@ -257,7 +259,7 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
257259
let line = self.errors.last().map(|e| e.line).unwrap_or(0);
258260
self.errors.push(Diagnostic {
259261
line, col: 0, end: 0,
260-
msg: "program too large: exceeded maximum instruction limit".into()
262+
msg: "program too large: exceeded maximum instruction limit".to_string()
261263
});
262264
}
263265

compiler/src/modules/vm/builtins.rs

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use core::cell::RefCell;
55

66
use super::types::*;
77

8-
use alloc::{string::{String, ToString}, vec::Vec, vec, rc::Rc, format};
8+
use alloc::{string::{String, ToString}, vec::Vec, vec, rc::Rc};
99

1010
impl<'a> VM<'a> {
1111

@@ -36,8 +36,8 @@ impl<'a> VM<'a> {
3636
HeapObj::Dict(v) => v.borrow().len() as i64,
3737
HeapObj::Set(v) => v.borrow().len() as i64,
3838
HeapObj::Range(s,e,st) => { let st=*st; ((e-s+st-st.signum())/st).max(0) }
39-
_ => return Err(VmErr::Type("len()".into())),
40-
}} else { return Err(VmErr::Type("len()".into())); };
39+
_ => return Err(VmErr::Type("object has no len()")),
40+
}} else { return Err(VmErr::Type("object has no len()")); };
4141
self.push(Val::int(n)); Ok(())
4242
}
4343

@@ -60,10 +60,10 @@ impl<'a> VM<'a> {
6060
let v = self.bigint_to_val(ab)?;
6161
self.push(v);
6262
} else {
63-
return Err(VmErr::Type("abs()".into()));
63+
return Err(VmErr::Type("abs() requires a number"));
6464
}
6565
} else {
66-
return Err(VmErr::Type("abs()".into()));
66+
return Err(VmErr::Type("abs() requires a number"));
6767
}
6868
Ok(())
6969
}
@@ -97,10 +97,10 @@ impl<'a> VM<'a> {
9797
else if o.is_float() { o.as_float() as i64 }
9898
else if o.is_bool() { o.as_bool() as i64 }
9999
else if o.is_heap() { match self.heap.get(o) {
100-
HeapObj::Str(s) => s.trim().parse().map_err(|_| VmErr::Value(format!("int: '{}'", s)))?,
101-
_ => return Err(VmErr::Type("int()".into())),
100+
HeapObj::Str(s) => s.trim().parse().map_err(|_| VmErr::Value("int(): invalid literal"))?,
101+
_ => return Err(VmErr::Type("int() requires a number or string")),
102102
}}
103-
else { return Err(VmErr::Type("int()".into())); };
103+
else { return Err(VmErr::Type("int() requires a number or string")); };
104104
let v = self.bigint_to_val(BigInt::from_i64(i))?;
105105
self.push(v); Ok(())
106106
}
@@ -115,11 +115,11 @@ impl<'a> VM<'a> {
115115
let f = if o.is_float() { o.as_float() }
116116
else if o.is_int() { o.as_int() as f64 }
117117
else if o.is_heap() { match self.heap.get(o) {
118-
HeapObj::Str(s) => s.trim().parse().map_err(|_| VmErr::Value(format!("float: '{}'", s)))?,
118+
HeapObj::Str(s) => s.trim().parse().map_err(|_| VmErr::Value("float(): invalid literal"))?,
119119
HeapObj::BigInt(b) => b.to_f64(),
120-
_ => return Err(VmErr::Type("float()".into()))
120+
_ => return Err(VmErr::Type("float() requires a number or string"))
121121
}}
122-
else { return Err(VmErr::Type("float()".into())); };
122+
else { return Err(VmErr::Type("float() requires a number or string")); };
123123
self.push(Val::float(f)); Ok(())
124124
}
125125

@@ -138,8 +138,8 @@ impl<'a> VM<'a> {
138138

139139
pub fn call_chr(&mut self) -> Result<(), VmErr> {
140140
let o = self.pop()?;
141-
if !o.is_int() { return Err(VmErr::Type("chr()".into())); }
142-
let c = char::from_u32(o.as_int() as u32).ok_or(VmErr::Value("chr()".into()))?;
141+
if !o.is_int() { return Err(VmErr::Type("chr() requires an integer")); }
142+
let c = char::from_u32(o.as_int() as u32).ok_or(VmErr::Value("chr() arg out of range"))?;
143143
let v = self.heap.alloc(HeapObj::Str(c.to_string()))?; self.push(v); Ok(())
144144
}
145145

@@ -153,7 +153,7 @@ impl<'a> VM<'a> {
153153
}
154154
}
155155
}
156-
Err(VmErr::Type("ord() requires string of length 1".into()))
156+
Err(VmErr::Type("ord() requires string of length 1"))
157157
}
158158

159159
/*
@@ -164,15 +164,15 @@ impl<'a> VM<'a> {
164164
pub fn call_range(&mut self, op: u16) -> Result<(), VmErr> {
165165
let args = self.pop_n(op as usize)?;
166166
let gi = |v: Val| -> Result<i64, VmErr> {
167-
if v.is_int() { Ok(v.as_int()) } else { Err(VmErr::Type("range() args must be int".into())) }
167+
if v.is_int() { Ok(v.as_int()) } else { Err(VmErr::Type("range() arguments must be integers")) }
168168
};
169169
let (s, e, st) = match args.len() {
170170
1 => (0, gi(args[0])?, 1),
171171
2 => (gi(args[0])?, gi(args[1])?, 1),
172172
3 => (gi(args[0])?, gi(args[1])?, gi(args[2])?),
173-
_ => return Err(VmErr::Type("range() takes 1-3 arguments".into())),
173+
_ => return Err(VmErr::Type("range() takes 1 to 3 arguments")),
174174
};
175-
if st == 0 { return Err(VmErr::Value("range() step cannot be zero".into())); }
175+
if st == 0 { return Err(VmErr::Value("range() step cannot be zero")); }
176176
let val = self.heap.alloc(HeapObj::Range(s, e, st))?;
177177
self.push(val); Ok(())
178178
}
@@ -192,7 +192,7 @@ impl<'a> VM<'a> {
192192
(Some(o), None) if o.is_float() => Val::int(fround(o.as_float()) as i64),
193193
(Some(o), _) if o.is_int() => *o,
194194
(Some(o), _) if o.is_heap() && matches!(self.heap.get(*o), HeapObj::BigInt(_)) => *o,
195-
_ => return Err(VmErr::Type("round()".into())),
195+
_ => return Err(VmErr::Type("round() requires a number")),
196196
};
197197
self.push(v); Ok(())
198198
}
@@ -205,7 +205,7 @@ impl<'a> VM<'a> {
205205
pub fn call_min(&mut self, op: u16) -> Result<(), VmErr> {
206206
let args: Vec<Val> = self.pop_n(op as usize)?;
207207
let items = self.unwrap_single_iterable(args)?;
208-
if items.is_empty() { return Err(VmErr::Type("min() arg is empty sequence".into())); }
208+
if items.is_empty() { return Err(VmErr::Value("min() arg is an empty sequence")); }
209209
let m = items[1..].iter().try_fold(items[0], |m, &x| {
210210
self.lt_vals(x, m).map(|lt| if lt { x } else { m })
211211
})?;
@@ -215,7 +215,7 @@ impl<'a> VM<'a> {
215215
pub fn call_max(&mut self, op: u16) -> Result<(), VmErr> {
216216
let args = self.pop_n(op as usize)?;
217217
let items = self.unwrap_single_iterable(args)?;
218-
if items.is_empty() { return Err(VmErr::Type("max() arg is empty sequence".into())); }
218+
if items.is_empty() { return Err(VmErr::Value("max() arg is an empty sequence")); }
219219
let m = items[1..].iter().try_fold(items[0], |m, &x| {
220220
self.lt_vals(m, x).map(|lt| if lt { x } else { m })
221221
})?;
@@ -229,7 +229,7 @@ impl<'a> VM<'a> {
229229

230230
pub fn call_sum(&mut self, op: u16) -> Result<(), VmErr> {
231231
let args = self.pop_n(op as usize)?;
232-
if args.is_empty() { return Err(VmErr::Type("sum() requires at least 1 argument".into())); }
232+
if args.is_empty() { return Err(VmErr::Type("sum() requires at least 1 argument")); }
233233
let start = if args.len() > 1 { args[1] } else { Val::int(0) };
234234
let items = self.extract_iterable(args[0])?;
235235
let mut acc = start;
@@ -280,8 +280,8 @@ impl<'a> VM<'a> {
280280
let items: Vec<Val> = if o.is_heap() { match self.heap.get(o) {
281281
HeapObj::Tuple(v) => v.clone(),
282282
HeapObj::List(v) => v.borrow().clone(),
283-
_ => return Err(VmErr::Type("tuple()".into())),
284-
}} else { return Err(VmErr::Type("tuple()".into())); };
283+
_ => return Err(VmErr::Type("tuple() argument must be iterable")),
284+
}} else { return Err(VmErr::Type("tuple() argument must be iterable")); };
285285
let val = self.heap.alloc(HeapObj::Tuple(items))?;
286286
self.push(val); Ok(())
287287
}
@@ -337,14 +337,14 @@ impl<'a> VM<'a> {
337337
let check = |t: Val, heap: &HeapPool| -> Result<bool, VmErr> {
338338
match heap.get(t) {
339339
HeapObj::Type(name) => Ok(name == &obj_ty),
340-
_ => Err(VmErr::Type("isinstance() arg 2 must be a type or tuple".into())),
340+
_ => Err(VmErr::Type("isinstance() arg 2 must be a type or tuple of types")),
341341
}
342342
};
343343

344344
let result = match self.heap.get(arg2) {
345345
HeapObj::Type(_) => check(arg2, &self.heap)?,
346346
HeapObj::Tuple(items) => items.iter().any(|&t| check(t, &self.heap).unwrap_or(false)),
347-
_ => return Err(VmErr::Type("isinstance() arg 2 must be a type or tuple".into())),
347+
_ => return Err(VmErr::Type("isinstance() arg 2 must be a type or tuple of types")),
348348
};
349349

350350
self.push(Val::bool(result));
@@ -386,12 +386,12 @@ impl<'a> VM<'a> {
386386
*/
387387

388388
fn extract_iterable(&self, o: Val) -> Result<Vec<Val>, VmErr> {
389-
if !o.is_heap() { return Err(VmErr::Type("argument is not iterable".into())); }
389+
if !o.is_heap() { return Err(VmErr::Type("object is not iterable")); }
390390
Ok(match self.heap.get(o) {
391391
HeapObj::List(v) => v.borrow().clone(),
392392
HeapObj::Tuple(v) => v.clone(),
393393
HeapObj::Set(v) => v.borrow().clone(),
394-
_ => return Err(VmErr::Type("argument is not iterable".into())),
394+
_ => return Err(VmErr::Type("object is not iterable")),
395395
})
396396
}
397397

@@ -401,7 +401,7 @@ impl<'a> VM<'a> {
401401
*/
402402

403403
fn extract_iterable_full(&self, o: Val) -> Result<Vec<Val>, VmErr> {
404-
if !o.is_heap() { return Err(VmErr::Type("list()".into())); }
404+
if !o.is_heap() { return Err(VmErr::Type("list() argument must be iterable")); }
405405
Ok(match self.heap.get(o) {
406406
HeapObj::List(v) => v.borrow().clone(),
407407
HeapObj::Tuple(v) => v.clone(),
@@ -413,7 +413,7 @@ impl<'a> VM<'a> {
413413
else { while cur > end { v.push(Val::int(cur)); cur += step; } }
414414
v
415415
}
416-
_ => return Err(VmErr::Type("list()".into())),
416+
_ => return Err(VmErr::Type("list() argument must be iterable")),
417417
})
418418
}
419419
}

0 commit comments

Comments
 (0)