Separate `print` and `println`

pull/4/head
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 {
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) => {

View File

@ -13,4 +13,9 @@ 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

View File

@ -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

View File

@ -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);
}

View File

@ -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
}