1
1
Fork 0
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:
azur 2022-12-14 13:32:02 +07:00
parent 0a62f14571
commit 7248580e24
5 changed files with 55 additions and 45 deletions

View file

@ -63,12 +63,16 @@ impl Compiler {
for x in xs { for x in xs {
instrs.extend(self.compile_expr(x.0)); instrs.extend(self.compile_expr(x.0));
} }
if f.0 == Expr::Sym("print".to_string()) { if let Expr::Sym(fname) = &f.0 {
instrs.push(Instr::Print); match fname.as_str() {
} else { "print" => instrs.push(Instr::Print),
instrs.extend(self.compile_expr(f.0)); "println" => instrs.push(Instr::PrintLn),
instrs.push(Instr::FuncApply); _ => {
} instrs.extend(self.compile_expr(f.0));
instrs.push(Instr::FuncApply);
}
}
};
instrs instrs
} }
Expr::Let(binds, body) => { Expr::Let(binds, body) => {

View file

@ -14,3 +14,8 @@ fun main = do
let result = add(34, 35) let result = add(34, 35)
println(result) println(result)
end end
fun main = do
let add = \x y -> x + y in
print(add(34, succ(34)))
end

View file

@ -1,22 +1,18 @@
// start
fun foo x = do fun foo x = do
69 // unused
print("Hi")
x x
end end
/* block comment
fun invalid =
*/
fun fac n = if n == 0 then 1 else n * fac(n - 1) fun fac n = if n == 0 then 1 else n * fac(n - 1)
fun main = do fun main = do
print(foo(1)) let succ = \x -> x + 1,
print(fac(5)) n = 34,
end in
println(n + succ(n))
// end print("Hello ")
println("World!")
println(foo(1))
println(fac(5))
end

View file

@ -101,23 +101,13 @@ impl Executor {
.get(self.ip) .get(self.ip)
.ok_or_else(|| self.err("invalid instruction pointer"))?; .ok_or_else(|| self.err("invalid instruction pointer"))?;
macro_rules! impl_num_binop { macro_rules! impl_binop {
($op:tt, $ret:ident) => { ($op:tt, $inp:ident, $ret:ident) => {
match (self.pop()?, self.pop()?) { 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)); self.stack.push(Value::$ret(a $op b));
} }
_ => return Err(Error::make("can't apply operator to non-numbers", self.ip)), _ => return Err(Error::make(format!("can't apply operator to non-{}", stringify!($inp)).as_str(), 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)),
} }
}; };
} }
@ -126,18 +116,18 @@ impl Executor {
Instr::NumPush(x) => { Instr::NumPush(x) => {
self.push(Value::Num(*x))?; self.push(Value::Num(*x))?;
} }
Instr::NumAdd => impl_num_binop!(+, Num), Instr::NumAdd => impl_binop!(+, Num, Num),
Instr::NumSub => impl_num_binop!(-, Num), Instr::NumSub => impl_binop!(-, Num, Num),
Instr::NumMul => impl_num_binop!(*, Num), Instr::NumMul => impl_binop!(*, Num, Num),
Instr::NumDiv => impl_num_binop!(/, Num), Instr::NumDiv => impl_binop!(/, Num, Num),
Instr::NumMod => impl_num_binop!(%, Num), Instr::NumMod => impl_binop!(%, Num, Num),
Instr::NumEq => impl_num_binop!(==, Bool), Instr::NumEq => impl_binop!(==, Num, Bool),
Instr::BoolPush(x) => { Instr::BoolPush(x) => {
self.push(Value::Bool(*x))?; self.push(Value::Bool(*x))?;
} }
Instr::BoolAnd => impl_bool_binop!(&&), Instr::BoolAnd => impl_binop!(&&, Bool, Bool),
Instr::BoolOr => impl_bool_binop!(||), Instr::BoolOr => impl_binop!(||, Bool, Bool),
Instr::BoolNot => { Instr::BoolNot => {
if let Value::Bool(b) = self.pop()? { if let Value::Bool(b) = self.pop()? {
self.push(Value::Bool(!b))?; self.push(Value::Bool(!b))?;
@ -149,7 +139,13 @@ impl Executor {
Instr::StrPush(x) => { Instr::StrPush(x) => {
self.push(Value::Str(x.clone()))?; 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 => { Instr::Pop => {
self.pop()?; self.pop()?;
} }
@ -273,6 +269,10 @@ impl Executor {
} }
Instr::Print => { Instr::Print => {
let v = self.pop()?;
print!("{}", v);
}
Instr::PrintLn => {
let v = self.pop()?; let v = self.pop()?;
println!("{}", v); println!("{}", v);
} }

View file

@ -124,6 +124,7 @@ pub enum Instr {
// └─╼ null delimiter // └─╼ null delimiter
// Total of 15 bytes (1 + 13 + 1) // Total of 15 bytes (1 + 13 + 1)
StrPush(String), // 1 + string.len() + 1 bytes StrPush(String), // 1 + string.len() + 1 bytes
StrConcat, // 1 byte
Pop, // ┐ 1 byte Pop, // ┐ 1 byte
Dup, // ┘ Dup, // ┘
@ -163,7 +164,8 @@ pub enum Instr {
Jump(usize), // ┐ 9 bytes: 1 byte for the enum, 8 bytes for the usize (64-bit) Jump(usize), // ┐ 9 bytes: 1 byte for the enum, 8 bytes for the usize (64-bit)
JumpIfFalse(usize), // ┘ JumpIfFalse(usize), // ┘
Print, // 1 byte Print, // ┐ 1 byte
PrintLn, // ┘
} }
static mut INSTR_INDEX: Cell<u8> = Cell::new(0); static mut INSTR_INDEX: Cell<u8> = Cell::new(0);
@ -183,6 +185,7 @@ impl Instr {
Instr::BoolAnd | Instr::BoolOr | Instr::BoolNot => 1, Instr::BoolAnd | Instr::BoolOr | Instr::BoolNot => 1,
Instr::StrPush(s) => 1 + s.len() + 1, Instr::StrPush(s) => 1 + s.len() + 1,
Instr::StrConcat => 1,
Instr::Pop | Instr::Dup => 1, Instr::Pop | Instr::Dup => 1,
@ -204,7 +207,7 @@ impl Instr {
Instr::Jump(_) | Instr::JumpIfFalse(_) => 1 + std::mem::size_of::<usize>(), 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.extend(s.as_bytes());
bytes.push(0x00); bytes.push(0x00);
} }
Instr::StrConcat => bytes.push(index!()),
Instr::Pop => bytes.push(index!()), Instr::Pop => bytes.push(index!()),
Instr::Dup => bytes.push(index!()), Instr::Dup => bytes.push(index!()),
@ -307,6 +311,7 @@ impl Instr {
} }
Instr::Print => bytes.push(index!()), Instr::Print => bytes.push(index!()),
Instr::PrintLn => bytes.push(index!()),
} }
bytes bytes
} }