Added non-newline print.
This commit is contained in:
parent
fd97655e04
commit
6ad0ab5e29
|
@ -136,7 +136,10 @@ pub enum Stmt {
|
||||||
expr: Spanned<Expr>,
|
expr: Spanned<Expr>,
|
||||||
args: Vec<Spanned<Expr>>,
|
args: Vec<Spanned<Expr>>,
|
||||||
},
|
},
|
||||||
Print(Spanned<Expr>),
|
Print {
|
||||||
|
expr: Spanned<Expr>,
|
||||||
|
newline: bool,
|
||||||
|
},
|
||||||
Read(Assignable),
|
Read(Assignable),
|
||||||
Melo(Spanned<String>),
|
Melo(Spanned<String>),
|
||||||
Rlyeh,
|
Rlyeh,
|
||||||
|
|
|
@ -214,8 +214,14 @@ impl ExecEnv {
|
||||||
/// Perform the action indicated by a statement.
|
/// Perform the action indicated by a statement.
|
||||||
fn eval_stmt(&mut self, stmt: &Spanned<Stmt>) -> Result<HaltStatus, Error> {
|
fn eval_stmt(&mut self, stmt: &Spanned<Stmt>) -> Result<HaltStatus, Error> {
|
||||||
match &stmt.item {
|
match &stmt.item {
|
||||||
Stmt::Print(expr) => {
|
Stmt::Print { expr, newline } => {
|
||||||
println!("{}", self.eval_expr(expr)?);
|
let value = self.eval_expr(expr)?;
|
||||||
|
if *newline {
|
||||||
|
println!("{value}");
|
||||||
|
} else {
|
||||||
|
print!("{value}");
|
||||||
|
stdout().lock().flush()?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Stmt::Dim { ident, init } => {
|
Stmt::Dim { ident, init } => {
|
||||||
let init = match init {
|
let init = match init {
|
||||||
|
|
|
@ -363,10 +363,24 @@ impl<'source> Parser<'source> {
|
||||||
match self.checked_next()? {
|
match self.checked_next()? {
|
||||||
// Print to stdout
|
// Print to stdout
|
||||||
Token::Print => {
|
Token::Print => {
|
||||||
let stmt = Stmt::Print(buf.take().ok_or_else(|| {
|
break Stmt::Print {
|
||||||
Error::new(ErrorKind::UnexpectedToken(Token::Print), self.lexer.span())
|
expr: buf.take().ok_or_else(|| {
|
||||||
})?);
|
Error::new(ErrorKind::UnexpectedToken(Token::Print), self.lexer.span())
|
||||||
break self.semicolon_terminated(stmt)?;
|
})?,
|
||||||
|
newline: match self.checked_next()? {
|
||||||
|
Token::Semicolon => true,
|
||||||
|
Token::Minus => {
|
||||||
|
self.require(Token::Semicolon)?;
|
||||||
|
false
|
||||||
|
}
|
||||||
|
token => {
|
||||||
|
return Err(Error::new(
|
||||||
|
ErrorKind::UnexpectedToken(token),
|
||||||
|
self.lexer.span(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Functio call
|
// Functio call
|
||||||
|
@ -642,40 +656,43 @@ mod tests {
|
||||||
fn simple_math() {
|
fn simple_math() {
|
||||||
let code = "1 * (num + 3) / 666 print;";
|
let code = "1 * (num + 3) / 666 print;";
|
||||||
let expected = &[Spanned {
|
let expected = &[Spanned {
|
||||||
item: Stmt::Print(Spanned {
|
item: Stmt::Print {
|
||||||
item: Expr::BinOp {
|
expr: Spanned {
|
||||||
lhs: Box::new(Spanned {
|
item: Expr::BinOp {
|
||||||
item: Expr::BinOp {
|
lhs: Box::new(Spanned {
|
||||||
lhs: Box::new(Spanned {
|
item: Expr::BinOp {
|
||||||
item: Expr::Literal(Literal::Int(1)),
|
lhs: Box::new(Spanned {
|
||||||
span: 0..1,
|
item: Expr::Literal(Literal::Int(1)),
|
||||||
}),
|
span: 0..1,
|
||||||
rhs: Box::new(Spanned {
|
}),
|
||||||
item: Expr::BinOp {
|
rhs: Box::new(Spanned {
|
||||||
lhs: Box::new(Spanned {
|
item: Expr::BinOp {
|
||||||
item: Expr::Variable("num".to_owned()),
|
lhs: Box::new(Spanned {
|
||||||
span: 5..6,
|
item: Expr::Variable("num".to_owned()),
|
||||||
}),
|
span: 5..6,
|
||||||
rhs: Box::new(Spanned {
|
}),
|
||||||
item: Expr::Literal(Literal::Int(3)),
|
rhs: Box::new(Spanned {
|
||||||
span: 9..10,
|
item: Expr::Literal(Literal::Int(3)),
|
||||||
}),
|
span: 9..10,
|
||||||
kind: BinOpKind::Add,
|
}),
|
||||||
},
|
kind: BinOpKind::Add,
|
||||||
span: 5..10,
|
},
|
||||||
}),
|
span: 5..10,
|
||||||
kind: BinOpKind::Multiply,
|
}),
|
||||||
},
|
kind: BinOpKind::Multiply,
|
||||||
span: 0..11,
|
},
|
||||||
}),
|
span: 0..11,
|
||||||
rhs: Box::new(Spanned {
|
}),
|
||||||
item: Expr::Literal(Literal::Int(666)),
|
rhs: Box::new(Spanned {
|
||||||
span: 14..17,
|
item: Expr::Literal(Literal::Int(666)),
|
||||||
}),
|
span: 14..17,
|
||||||
kind: BinOpKind::Divide,
|
}),
|
||||||
|
kind: BinOpKind::Divide,
|
||||||
|
},
|
||||||
|
span: 0..17,
|
||||||
},
|
},
|
||||||
span: 0..17,
|
newline: true,
|
||||||
}),
|
},
|
||||||
span: 0..24,
|
span: 0..24,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
@ -724,10 +741,13 @@ mod tests {
|
||||||
span: 8..21,
|
span: 8..21,
|
||||||
},
|
},
|
||||||
body: vec![Spanned {
|
body: vec![Spanned {
|
||||||
item: Stmt::Print(Spanned {
|
item: Stmt::Print {
|
||||||
item: Expr::Literal(Literal::Str("Buy Able products!".to_owned())),
|
expr: Spanned {
|
||||||
span: 25..47,
|
item: Expr::Literal(Literal::Str("Buy Able products!".to_owned())),
|
||||||
}),
|
span: 25..47,
|
||||||
|
},
|
||||||
|
newline: true,
|
||||||
|
},
|
||||||
span: 25..54,
|
span: 25..54,
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
|
@ -773,41 +793,44 @@ mod tests {
|
||||||
fn cart_construction() {
|
fn cart_construction() {
|
||||||
let code = "[/*able*/ <= 1, /*script*/ <= 3 - 1] print;";
|
let code = "[/*able*/ <= 1, /*script*/ <= 3 - 1] print;";
|
||||||
let expected = &[Spanned {
|
let expected = &[Spanned {
|
||||||
item: Stmt::Print(Spanned {
|
item: Stmt::Print {
|
||||||
item: Expr::Cart(vec![
|
expr: Spanned {
|
||||||
(
|
item: Expr::Cart(vec![
|
||||||
Spanned {
|
(
|
||||||
item: Expr::Literal(Literal::Str("able".to_owned())),
|
Spanned {
|
||||||
span: 1..7,
|
item: Expr::Literal(Literal::Str("able".to_owned())),
|
||||||
},
|
span: 1..7,
|
||||||
Spanned {
|
|
||||||
item: Expr::Literal(Literal::Int(1)),
|
|
||||||
span: 11..12,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Spanned {
|
|
||||||
item: Expr::Literal(Literal::Str("script".to_owned())),
|
|
||||||
span: 14..22,
|
|
||||||
},
|
|
||||||
Spanned {
|
|
||||||
item: Expr::BinOp {
|
|
||||||
kind: BinOpKind::Subtract,
|
|
||||||
lhs: Box::new(Spanned {
|
|
||||||
item: Expr::Literal(Literal::Int(3)),
|
|
||||||
span: 26..27,
|
|
||||||
}),
|
|
||||||
rhs: Box::new(Spanned {
|
|
||||||
item: Expr::Literal(Literal::Int(1)),
|
|
||||||
span: 30..31,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
span: 26..31,
|
Spanned {
|
||||||
},
|
item: Expr::Literal(Literal::Int(1)),
|
||||||
),
|
span: 11..12,
|
||||||
]),
|
},
|
||||||
span: 0..32,
|
),
|
||||||
}),
|
(
|
||||||
|
Spanned {
|
||||||
|
item: Expr::Literal(Literal::Str("script".to_owned())),
|
||||||
|
span: 14..22,
|
||||||
|
},
|
||||||
|
Spanned {
|
||||||
|
item: Expr::BinOp {
|
||||||
|
kind: BinOpKind::Subtract,
|
||||||
|
lhs: Box::new(Spanned {
|
||||||
|
item: Expr::Literal(Literal::Int(3)),
|
||||||
|
span: 26..27,
|
||||||
|
}),
|
||||||
|
rhs: Box::new(Spanned {
|
||||||
|
item: Expr::Literal(Literal::Int(1)),
|
||||||
|
span: 30..31,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
span: 26..31,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
span: 0..32,
|
||||||
|
},
|
||||||
|
newline: true,
|
||||||
|
},
|
||||||
span: 0..39,
|
span: 0..39,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
@ -819,28 +842,31 @@ mod tests {
|
||||||
fn cart_index() {
|
fn cart_index() {
|
||||||
let code = "[/*able*/ <= /*ablecorp*/][/*ablecorp*/] print;";
|
let code = "[/*able*/ <= /*ablecorp*/][/*ablecorp*/] print;";
|
||||||
let expected = &[Spanned {
|
let expected = &[Spanned {
|
||||||
item: Stmt::Print(Spanned {
|
item: Stmt::Print {
|
||||||
item: Expr::Index {
|
expr: Spanned {
|
||||||
expr: Box::new(Spanned {
|
item: Expr::Index {
|
||||||
item: Expr::Cart(vec![(
|
expr: Box::new(Spanned {
|
||||||
Spanned {
|
item: Expr::Cart(vec![(
|
||||||
item: Expr::Literal(Literal::Str("able".to_owned())),
|
Spanned {
|
||||||
span: 1..7,
|
item: Expr::Literal(Literal::Str("able".to_owned())),
|
||||||
},
|
span: 1..7,
|
||||||
Spanned {
|
},
|
||||||
item: Expr::Literal(Literal::Str("ablecorp".to_owned())),
|
Spanned {
|
||||||
span: 11..21,
|
item: Expr::Literal(Literal::Str("ablecorp".to_owned())),
|
||||||
},
|
span: 11..21,
|
||||||
)]),
|
},
|
||||||
span: 0..22,
|
)]),
|
||||||
}),
|
span: 0..22,
|
||||||
index: Box::new(Spanned {
|
}),
|
||||||
item: Expr::Literal(Literal::Str("ablecorp".to_owned())),
|
index: Box::new(Spanned {
|
||||||
span: 23..33,
|
item: Expr::Literal(Literal::Str("ablecorp".to_owned())),
|
||||||
}),
|
span: 23..33,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
span: 0..34,
|
||||||
},
|
},
|
||||||
span: 0..34,
|
newline: true,
|
||||||
}),
|
},
|
||||||
span: 0..41,
|
span: 0..41,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue