From 6de41e64be00e560f9c84214c473503f45a097c5 Mon Sep 17 00:00:00 2001 From: rvcas Date: Tue, 4 Oct 2022 17:03:21 -0400 Subject: [PATCH] feat: add simple check command --- Cargo.lock | 1 + crates/cli/Cargo.toml | 1 + crates/cli/src/args.rs | 5 +++ crates/cli/src/main.rs | 15 +++++++++ crates/lang/src/parser.rs | 20 ++++++++++-- examples/syntax.ak | 17 ++++++++++ syntax.txt | 66 --------------------------------------- 7 files changed, 57 insertions(+), 68 deletions(-) create mode 100644 examples/syntax.ak delete mode 100644 syntax.txt diff --git a/Cargo.lock b/Cargo.lock index a21873f3..ec386933 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,7 @@ dependencies = [ name = "aiken" version = "0.0.18" dependencies = [ + "aiken-lang", "anyhow", "clap", "hex", diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 6a46ede9..4fdee605 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -20,3 +20,4 @@ pallas-traverse = "0.14.0-alpha.3" serde = { version = "1.0.144", features = ["derive"] } serde_json = "1.0.85" uplc = { path = '../uplc', version = "0.0.18" } +aiken-lang = { path = "../lang", version = "0.0.17" } diff --git a/crates/cli/src/args.rs b/crates/cli/src/args.rs index c8a6b5f3..79952fc5 100644 --- a/crates/cli/src/args.rs +++ b/crates/cli/src/args.rs @@ -9,6 +9,11 @@ use clap::{Parser, Subcommand}; pub enum Args { /// Build an aiken project Build, + /// Check a file or project + Check { + /// Specific aiken file to check + input: Option, + }, /// Start a development server Dev, /// Create a new aiken project diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 78a7b92b..0047af42 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -33,6 +33,21 @@ fn main() -> anyhow::Result<()> { todo!() } + Args::Check { input } => { + if let Some(input) = input { + let src = fs::read_to_string(&input)?; + + match aiken_lang::parser::script(&src) { + Ok(_) => (), + Err(errs) => { + for err in errs { + eprintln!("{:#?}", err); + } + } + } + } + } + Args::Dev => { // launch a development server // this should allow people to test diff --git a/crates/lang/src/parser.rs b/crates/lang/src/parser.rs index 52c6488e..7be388ee 100644 --- a/crates/lang/src/parser.rs +++ b/crates/lang/src/parser.rs @@ -2,12 +2,26 @@ use chumsky::prelude::*; use vec1::Vec1; use crate::{ - ast::{self, BinOp, Span, TodoKind, CAPTURE_VARIABLE}, + ast::{self, BinOp, Span, SrcId, TodoKind, CAPTURE_VARIABLE}, error::ParseError, - expr, + expr, lexer, token::Token, }; +pub fn script(src: &str) -> Result> { + let len = src.chars().count(); + + let span = |i| Span::new(SrcId::empty(), i..i + 1); + + let tokens = lexer::lexer().parse(chumsky::Stream::from_iter( + span(len), + src.chars().enumerate().map(|(i, c)| (c, span(i))), + ))?; + + module_parser(ast::ModuleKind::Script) + .parse(chumsky::Stream::from_iter(span(len), tokens.into_iter())) +} + pub fn module_parser( kind: ast::ModuleKind, ) -> impl Parser { @@ -86,6 +100,7 @@ pub fn data_parser() -> impl Parser name} @@ -828,6 +843,7 @@ pub fn labeled_constructor_type_args( location: span, }) .separated_by(just(Token::Comma)) + .allow_trailing() .delimited_by(just(Token::LeftBrace), just(Token::RightBrace)) } diff --git a/examples/syntax.ak b/examples/syntax.ak new file mode 100644 index 00000000..102e5a22 --- /dev/null +++ b/examples/syntax.ak @@ -0,0 +1,17 @@ +use aiken/context.{ScriptContext} + +pub type Datum { + something: String, +} + +pub type Redeemer { + Buy + Sell +} + +pub fn validate(datum: Datum, rdmr: Redeemer, ctx: ScriptContext) -> Bool { + when rdmr is { + Buy -> True + Sell -> datum.something == "Aiken" + } +} \ No newline at end of file diff --git a/syntax.txt b/syntax.txt deleted file mode 100644 index b71a8d3e..00000000 --- a/syntax.txt +++ /dev/null @@ -1,66 +0,0 @@ -// imports -use std/address.Address as A // alias - -use std/list.{map, foldl} // access module members in one import - -// `///` used for document generation - -// Records (single constructor `data` type) -pub type Datum { - signer: Address, -} - -// above is suger for -pub type Datum { - Datum { signer: Address }, -} - -// type aliases -type A = Address - -// multiple constructors and a `generic` -pub type Redeemer(a) { - // records wrapped in parens - Buy(Address, a), - // records wrapped in curlies - Sell { address: Address, some_thing: a }, -} - -pub fn main(datum: Datum, redeemer: Redeemer, ctx: ScriptContext) { - [1, 2, 3] - |> list.map(fn(x) -> x + 1) -} - -// named and anonymous functions -fn(x) -> x + 1 - -fn add_one(x) -> x + 1 - -fn(x: Int) -> x + 1 - -fn add_one(label x: Int) -> x + 1 - -fn(x: Int) { - x + 1 -} - -fn(x: Int) -> Int { - x + 1 -} - -fn add_one(x: Int) -> Int { - x + 1 -} - -// can be curried -fn add(a, b) { - a + 1 -} - -let add_one = add(1) - -// matching -when redeemer is { - Buyer(address, thing) -> do_stuff(), - Seller { address, some_thing } -> do_seller_stuff(), -}