diff --git a/crates/cli/src/args.rs b/crates/cli/src/args.rs index ef4c92ac..c8a6b5f3 100644 --- a/crates/cli/src/args.rs +++ b/crates/cli/src/args.rs @@ -81,6 +81,9 @@ pub enum UplcCommand { /// Print output instead of saving to file #[clap(short, long)] print: bool, + + #[clap(short, long)] + cbor_hex: bool, }, /// Format an Untyped Plutus Core program Fmt { @@ -103,6 +106,9 @@ pub enum UplcCommand { /// Print output instead of saving to file #[clap(short, long)] print: bool, + + #[clap(short, long)] + cbor_hex: bool, }, } diff --git a/crates/lang/src/parser.rs b/crates/lang/src/parser.rs index f320ffc5..00ed7872 100644 --- a/crates/lang/src/parser.rs +++ b/crates/lang/src/parser.rs @@ -1,7 +1,7 @@ use chumsky::prelude::*; use crate::{ - ast::{self, TodoKind}, + ast::{self, BinOp, TodoKind}, error::ParseError, expr, token::Token, @@ -259,7 +259,42 @@ pub fn expr_seq_parser() -> impl Parser impl Parser {} +pub fn expr_parser() -> impl Parser { + recursive(|r| { + let op = choice(( + just(Token::Star).to(BinOp::MultInt), + just(Token::Slash).to(BinOp::DivInt), + just(Token::Percent).to(BinOp::ModInt), + )); + + let product = expr_unit_parser() + .then(op.then(expr_unit_parser()).repeated()) + .foldl(|a, (op, b)| expr::UntypedExpr::BinOp { + location: a.location().union(b.location()), + name: op, + left: Box::new(a), + right: Box::new(b), + }) + .boxed(); + + let op = choice(( + just(Token::Plus).to(BinOp::AddInt), + just(Token::Minus).to(BinOp::SubInt), + )); + + let sum = product + .clone() + .then(op.then(product).repeated()) + .foldl(|a, (op, b)| expr::UntypedExpr::BinOp { + location: a.location().union(b.location()), + name: op, + left: Box::new(a), + right: Box::new(b), + }); + + sum + }) +} pub fn expr_unit_parser() -> impl Parser { choice(( @@ -512,7 +547,7 @@ mod tests { use crate::{ ast::{self, Span, SrcId}, - lexer, + expr, lexer, parser::module_parser, }; @@ -524,13 +559,13 @@ mod tests { use std/tx as t type Option(a) { - Some(a, Int) - None - Wow { name: Int, age: Int } + Some(a, Int) + None + Wow { name: Int, age: Int } } pub opaque type User { - name: _w + name: _w } type Thing = Option(Int) @@ -538,7 +573,7 @@ mod tests { pub type Me = Option(String) pub fn add_one(a) { - a + 1 + a + 1 } pub fn add_one(a: Int) -> Int { @@ -746,6 +781,35 @@ mod tests { public: true, tipo: (), }, + ast::UntypedDefinition::Fn { + arguments: vec![ast::Arg { + arg_name: ast::ArgName::Named { + name: "a".to_string(), + location: Span::new(SrcId::empty(), 430..431), + }, + location: Span::new(SrcId::empty(), 430..431), + annotation: None, + tipo: (), + },], + body: expr::UntypedExpr::BinOp { + location: Span::new(SrcId::empty(), 451..456), + name: ast::BinOp::AddInt, + left: Box::new(expr::UntypedExpr::Var { + location: Span::new(SrcId::empty(), 451..452), + name: "a".to_string(), + }), + right: Box::new(expr::UntypedExpr::Int { + location: Span::new(SrcId::empty(), 455..456), + value: "1".to_string(), + }), + }, + doc: None, + location: Span::new(SrcId::empty(), 415..470), + name: "add_one".to_string(), + public: true, + return_annotation: None, + return_type: (), + }, ] }, "{:#?}",