mirror of
https://github.com/azur1s/bobbylisp.git
synced 2024-10-16 02:37:40 -05:00
Separate print
and println
This commit is contained in:
parent
0a62f14571
commit
7248580e24
|
@ -63,12 +63,16 @@ impl Compiler {
|
|||
for x in xs {
|
||||
instrs.extend(self.compile_expr(x.0));
|
||||
}
|
||||
if f.0 == Expr::Sym("print".to_string()) {
|
||||
instrs.push(Instr::Print);
|
||||
} else {
|
||||
instrs.extend(self.compile_expr(f.0));
|
||||
instrs.push(Instr::FuncApply);
|
||||
}
|
||||
if let Expr::Sym(fname) = &f.0 {
|
||||
match fname.as_str() {
|
||||
"print" => instrs.push(Instr::Print),
|
||||
"println" => instrs.push(Instr::PrintLn),
|
||||
_ => {
|
||||
instrs.extend(self.compile_expr(f.0));
|
||||
instrs.push(Instr::FuncApply);
|
||||
}
|
||||
}
|
||||
};
|
||||
instrs
|
||||
}
|
||||
Expr::Let(binds, body) => {
|
||||
|
|
|
@ -14,3 +14,8 @@ fun main = do
|
|||
let result = add(34, 35)
|
||||
println(result)
|
||||
end
|
||||
|
||||
fun main = do
|
||||
let add = \x y -> x + y in
|
||||
print(add(34, succ(34)))
|
||||
end
|
|
@ -1,22 +1,18 @@
|
|||
// start
|
||||
|
||||
fun foo x = do
|
||||
69 // unused
|
||||
print("Hi")
|
||||
x
|
||||
end
|
||||
|
||||
/* block comment
|
||||
|
||||
fun invalid =
|
||||
|
||||
*/
|
||||
|
||||
fun fac n = if n == 0 then 1 else n * fac(n - 1)
|
||||
|
||||
fun main = do
|
||||
print(foo(1))
|
||||
print(fac(5))
|
||||
end
|
||||
let succ = \x -> x + 1,
|
||||
n = 34,
|
||||
in
|
||||
println(n + succ(n))
|
||||
|
||||
// end
|
||||
print("Hello ")
|
||||
println("World!")
|
||||
|
||||
println(foo(1))
|
||||
println(fac(5))
|
||||
end
|
|
@ -101,23 +101,13 @@ impl Executor {
|
|||
.get(self.ip)
|
||||
.ok_or_else(|| self.err("invalid instruction pointer"))?;
|
||||
|
||||
macro_rules! impl_num_binop {
|
||||
($op:tt, $ret:ident) => {
|
||||
macro_rules! impl_binop {
|
||||
($op:tt, $inp:ident, $ret:ident) => {
|
||||
match (self.pop()?, self.pop()?) {
|
||||
(Value::Num(a), Value::Num(b)) => {
|
||||
(Value::$inp(a), Value::$inp(b)) => {
|
||||
self.stack.push(Value::$ret(a $op b));
|
||||
}
|
||||
_ => return Err(Error::make("can't apply operator to non-numbers", self.ip)),
|
||||
}
|
||||
};
|
||||
}
|
||||
macro_rules! impl_bool_binop {
|
||||
($op:tt) => {
|
||||
match (self.pop()?, self.pop()?) {
|
||||
(Value::Bool(a), Value::Bool(b)) => {
|
||||
self.stack.push(Value::Bool(a $op b));
|
||||
}
|
||||
_ => return Err(Error::make("can't apply operator to non-booleans", self.ip)),
|
||||
_ => return Err(Error::make(format!("can't apply operator to non-{}", stringify!($inp)).as_str(), self.ip)),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -126,18 +116,18 @@ impl Executor {
|
|||
Instr::NumPush(x) => {
|
||||
self.push(Value::Num(*x))?;
|
||||
}
|
||||
Instr::NumAdd => impl_num_binop!(+, Num),
|
||||
Instr::NumSub => impl_num_binop!(-, Num),
|
||||
Instr::NumMul => impl_num_binop!(*, Num),
|
||||
Instr::NumDiv => impl_num_binop!(/, Num),
|
||||
Instr::NumMod => impl_num_binop!(%, Num),
|
||||
Instr::NumEq => impl_num_binop!(==, Bool),
|
||||
Instr::NumAdd => impl_binop!(+, Num, Num),
|
||||
Instr::NumSub => impl_binop!(-, Num, Num),
|
||||
Instr::NumMul => impl_binop!(*, Num, Num),
|
||||
Instr::NumDiv => impl_binop!(/, Num, Num),
|
||||
Instr::NumMod => impl_binop!(%, Num, Num),
|
||||
Instr::NumEq => impl_binop!(==, Num, Bool),
|
||||
|
||||
Instr::BoolPush(x) => {
|
||||
self.push(Value::Bool(*x))?;
|
||||
}
|
||||
Instr::BoolAnd => impl_bool_binop!(&&),
|
||||
Instr::BoolOr => impl_bool_binop!(||),
|
||||
Instr::BoolAnd => impl_binop!(&&, Bool, Bool),
|
||||
Instr::BoolOr => impl_binop!(||, Bool, Bool),
|
||||
Instr::BoolNot => {
|
||||
if let Value::Bool(b) = self.pop()? {
|
||||
self.push(Value::Bool(!b))?;
|
||||
|
@ -149,7 +139,13 @@ impl Executor {
|
|||
Instr::StrPush(x) => {
|
||||
self.push(Value::Str(x.clone()))?;
|
||||
}
|
||||
|
||||
Instr::StrConcat => {
|
||||
if let (Value::Str(a), Value::Str(b)) = (self.pop()?, self.pop()?) {
|
||||
self.push(Value::Str(a + &b))?;
|
||||
} else {
|
||||
return Err(Error::make("can't concatenate non-strings", self.ip));
|
||||
}
|
||||
}
|
||||
Instr::Pop => {
|
||||
self.pop()?;
|
||||
}
|
||||
|
@ -273,6 +269,10 @@ impl Executor {
|
|||
}
|
||||
|
||||
Instr::Print => {
|
||||
let v = self.pop()?;
|
||||
print!("{}", v);
|
||||
}
|
||||
Instr::PrintLn => {
|
||||
let v = self.pop()?;
|
||||
println!("{}", v);
|
||||
}
|
||||
|
|
|
@ -124,6 +124,7 @@ pub enum Instr {
|
|||
// └─╼ null delimiter
|
||||
// Total of 15 bytes (1 + 13 + 1)
|
||||
StrPush(String), // 1 + string.len() + 1 bytes
|
||||
StrConcat, // 1 byte
|
||||
|
||||
Pop, // ┐ 1 byte
|
||||
Dup, // ┘
|
||||
|
@ -163,7 +164,8 @@ pub enum Instr {
|
|||
Jump(usize), // ┐ 9 bytes: 1 byte for the enum, 8 bytes for the usize (64-bit)
|
||||
JumpIfFalse(usize), // ┘
|
||||
|
||||
Print, // 1 byte
|
||||
Print, // ┐ 1 byte
|
||||
PrintLn, // ┘
|
||||
}
|
||||
|
||||
static mut INSTR_INDEX: Cell<u8> = Cell::new(0);
|
||||
|
@ -183,6 +185,7 @@ impl Instr {
|
|||
Instr::BoolAnd | Instr::BoolOr | Instr::BoolNot => 1,
|
||||
|
||||
Instr::StrPush(s) => 1 + s.len() + 1,
|
||||
Instr::StrConcat => 1,
|
||||
|
||||
Instr::Pop | Instr::Dup => 1,
|
||||
|
||||
|
@ -204,7 +207,7 @@ impl Instr {
|
|||
|
||||
Instr::Jump(_) | Instr::JumpIfFalse(_) => 1 + std::mem::size_of::<usize>(),
|
||||
|
||||
Instr::Print => 1,
|
||||
Instr::Print | Instr::PrintLn => 1,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,6 +251,7 @@ impl Instr {
|
|||
bytes.extend(s.as_bytes());
|
||||
bytes.push(0x00);
|
||||
}
|
||||
Instr::StrConcat => bytes.push(index!()),
|
||||
|
||||
Instr::Pop => bytes.push(index!()),
|
||||
Instr::Dup => bytes.push(index!()),
|
||||
|
@ -307,6 +311,7 @@ impl Instr {
|
|||
}
|
||||
|
||||
Instr::Print => bytes.push(index!()),
|
||||
Instr::PrintLn => bytes.push(index!()),
|
||||
}
|
||||
bytes
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue