diff --git a/moon.mod.json b/moon.mod.json index 7050d65..732e52a 100644 --- a/moon.mod.json +++ b/moon.mod.json @@ -1,6 +1,6 @@ { "name": "tiye/cirru-parser", - "version": "0.0.9", + "version": "0.0.10", "deps": {}, "readme": "README.md", "repository": "https://github.com/Cirru/parser.mbt", diff --git a/src/lib/parser.mbt b/src/lib/parser.mbt index c8942a8..ebda89f 100644 --- a/src/lib/parser.mbt +++ b/src/lib/parser.mbt @@ -1,3 +1,4 @@ +///| fn build_exprs(tokens : Array[CirruLexItem]) -> Array[Cirru]!CirruParseError { let acc : Array[Cirru] = Array::new() let mut idx = 0 @@ -56,7 +57,7 @@ fn build_exprs(tokens : Array[CirruLexItem]) -> Array[Cirru]!CirruParseError { } } -/// main function to parse Cirru code into syntax tree +///| main function to parse Cirru code into syntax tree pub fn parse(code : String) -> Array[Cirru]!CirruParseError { let tokens = resolve_indentations(lex!(code)) // println("tokens: \{tokens}") @@ -65,15 +66,17 @@ pub fn parse(code : String) -> Array[Cirru]!CirruParseError { resolve_comma(resolve_dollar(tree)) } +///| type! CirruParseError String -/// display Cirru parse error +///| display Cirru parse error pub fn to_string(self : CirruParseError) -> String { match self { CirruParseError(s) => s } } +///| fn parse_indentation(size : Int) -> CirruLexItem!CirruParseError { if size % 2 == 0 { CirruLexItem::Indent(size >> 1) @@ -82,7 +85,7 @@ fn parse_indentation(size : Int) -> CirruLexItem!CirruParseError { } } -/// lexer is a simpler state machine to tokenize Cirru code +///| lexer is a simpler state machine to tokenize Cirru code fn lex(initial_code : String) -> Array[CirruLexItem]!CirruParseError { let acc = [] let mut state = CirruLexState::Indent @@ -264,7 +267,7 @@ fn lex(initial_code : String) -> Array[CirruLexItem]!CirruParseError { } } -/// internal function for figuring out indentations after lexing +///| internal function for figuring out indentations after lexing fn resolve_indentations(tokens : Array[CirruLexItem]) -> Array[CirruLexItem] { let size = tokens.length() let mut acc : Array[CirruLexItem] = Array::new() diff --git a/src/lib/parser_test.mbt b/src/lib/parser_test.mbt index 1a9b46a..bc6be5b 100644 --- a/src/lib/parser_test.mbt +++ b/src/lib/parser_test.mbt @@ -1,8 +1,7 @@ test "parser" { - assert_eq!( - @lib.parse!("def a"), - [@lib.Cirru::List([@lib.Cirru::Leaf("def"), @lib.Cirru::Leaf("a")])], - ) + assert_eq!(@lib.parse!("def a"), [ + @lib.Cirru::List([@lib.Cirru::Leaf("def"), @lib.Cirru::Leaf("a")]), + ]) } test "existed demos" { @@ -18,13 +17,15 @@ test "existed demos" { let defined = @json.parse?(json_file).unwrap() let defined_str = defined.stringify() assert_eq!(tree, defined_str) - - let formatted = @lib.format!(@json.from_json!(defined), {use_inline: false}) + let formatted = @lib.format!(@json.from_json!(defined), { + use_inline: false, + }) let ret = @lib.parse?(formatted).unwrap().to_json().stringify() assert_eq!(ret, defined_str) } } +///| pub extern "js" fn fsReadSync(path : String) -> String = #|(path) => { #| const fs = require("node:fs"); diff --git a/src/lib/primes.mbt b/src/lib/primes.mbt index 34e7c95..25b964e 100644 --- a/src/lib/primes.mbt +++ b/src/lib/primes.mbt @@ -70,7 +70,7 @@ fn Cirru::default() -> Cirru { } ///| -pub fn output(self : Cirru, logger : Logger) -> Unit { +pub fn output(self : Cirru, logger : &Logger) -> Unit { logger.write_string(self.to_string()) } @@ -176,7 +176,7 @@ enum CirruLexItem { } ///| -fn output(self : CirruLexItem, logger : Logger) -> Unit { +fn output(self : CirruLexItem, logger : &Logger) -> Unit { logger.write_string(self.to_string()) } diff --git a/src/lib/s_expr.mbt b/src/lib/s_expr.mbt index a1679d9..1687799 100644 --- a/src/lib/s_expr.mbt +++ b/src/lib/s_expr.mbt @@ -1,6 +1,7 @@ +///| type! FormatError String -/// format program to Cirru to Lisp-like code +///| format program to Cirru to Lisp-like code pub fn format_to_lisp(xs : Array[Cirru]) -> String!FormatError { let mut content : String = "\n" for expr in xs { @@ -9,7 +10,7 @@ pub fn format_to_lisp(xs : Array[Cirru]) -> String!FormatError { content } -/// format single expression to Lisp-like code +///| format single expression to Lisp-like code fn format_lispy_expr(self : Cirru, indent : Int) -> String!FormatError { let emptySpace = " " match self { @@ -62,6 +63,7 @@ fn format_lispy_expr(self : Cirru, indent : Int) -> String!FormatError { } } +///| fn ends_with_newline(s : String) -> Bool { for c in s.rev() { if c == 'c' { @@ -74,6 +76,7 @@ fn ends_with_newline(s : String) -> Bool { false } +///| fn gen_newline(n : Int) -> String { let mut chunk : String = "" chunk = "\{chunk}\n" @@ -83,7 +86,7 @@ fn gen_newline(n : Int) -> String { chunk } -/// `.escape_default()` in Rust +///| `.escape_default()` in Rust fn escape_string(s : String) -> String { let mut chunk : String = "" for c in s { diff --git a/src/lib/tree.mbt b/src/lib/tree.mbt index 60d8c0c..6634d39 100644 --- a/src/lib/tree.mbt +++ b/src/lib/tree.mbt @@ -1,3 +1,4 @@ +///| fn resolve_comma(xs : Array[Cirru]) -> Array[Cirru] { if xs.is_empty() { [] @@ -6,6 +7,7 @@ fn resolve_comma(xs : Array[Cirru]) -> Array[Cirru] { } } +///| fn comma_helper(initial_after : Array[Cirru]) -> Array[Cirru] { let before : Array[Cirru] = [] let after : Array[Cirru] = initial_after @@ -35,6 +37,7 @@ fn comma_helper(initial_after : Array[Cirru]) -> Array[Cirru] { } } +///| fn resolve_dollar(xs : Array[Cirru]) -> Array[Cirru] { if xs.is_empty() { [] @@ -43,6 +46,7 @@ fn resolve_dollar(xs : Array[Cirru]) -> Array[Cirru] { } } +///| fn dollar_helper(initial_after : Array[Cirru]) -> Array[Cirru] { let before : Array[Cirru] = [] let after : Array[Cirru] = initial_after diff --git a/src/lib/writer.mbt b/src/lib/writer.mbt index bc8efc3..c397bd1 100644 --- a/src/lib/writer.mbt +++ b/src/lib/writer.mbt @@ -1,3 +1,4 @@ +///| enum WriterNode { Nil Leaf @@ -6,18 +7,23 @@ enum WriterNode { Expr } derive(Eq) +///| let char_close : Char = ')' +///| let char_open : Char = '(' +///| let allowed_chars : String = "$-:<>[]{}*=+.,\\/!?~_@#&%^|;'" +///| fn is_a_digit(c : Char) -> Bool { let n = c.to_int() // ascii table https://tool.oschina.net/commons?type=4 n >= 48 && n <= 57 } +///| fn is_a_letter(c : Char) -> Bool { let n = c.to_int() if n >= 65 && n <= 90 { @@ -29,6 +35,7 @@ fn is_a_letter(c : Char) -> Bool { false } +///| fn is_simple_expr(ys : Array[Cirru]) -> Bool { for y in ys { match y { @@ -39,6 +46,7 @@ fn is_simple_expr(ys : Array[Cirru]) -> Bool { true } +///| fn is_boxed(ys : Array[Cirru]) -> Bool { for y in ys { match y { @@ -49,10 +57,12 @@ fn is_boxed(ys : Array[Cirru]) -> Bool { true } +///| fn is_simple_char(x : Char) -> Bool { is_a_letter(x) || is_a_digit(x) } +///| fn is_char_allowed(x : Char) -> Bool { if is_simple_char(x) { return true @@ -60,6 +70,7 @@ fn is_char_allowed(x : Char) -> Bool { allowed_chars.contains_char(x) } +///| fn generate_leaf(s : String) -> String { let mut all_allowed = true for x in s { @@ -89,10 +100,12 @@ fn generate_leaf(s : String) -> String { } } +///| fn generate_empty_expr() -> String { "()" } +///| fn generate_inline_expr(xs : Array[Cirru]) -> String { let mut result = char_open.to_string() for idx, x in xs { @@ -109,7 +122,7 @@ fn generate_inline_expr(xs : Array[Cirru]) -> String { result } -/// by 2 spaces +///| by 2 spaces fn push_spaces(buf : String, n : Int) -> String { let mut ret = buf // for _ in 0..n { @@ -121,6 +134,7 @@ fn push_spaces(buf : String, n : Int) -> String { return ret } +///| fn render_newline(n : Int) -> String { let mut ret = "" ret = ret + "\n" @@ -128,12 +142,12 @@ fn render_newline(n : Int) -> String { ret } -/// options for writer, `use_inline` for more compact format. +///| options for writer, `use_inline` for more compact format. pub(all) struct CirruWriterOptions { use_inline : Bool } -/// kind for writer nodes +///| kind for writer nodes fn get_node_kind(self : Cirru) -> WriterNode { match self { Cirru::Leaf(_) => WriterNode::Leaf @@ -150,14 +164,17 @@ fn get_node_kind(self : Cirru) -> WriterNode { } } +///| pub(all) type! FormatCirruError String +///| pub fn to_string(self : FormatCirruError) -> String { match self { FormatCirruError(s) => s } } +///| fn generate_tree( xs : Array[Cirru], insist_head : Bool, @@ -291,6 +308,7 @@ fn generate_tree( result } +///| fn generate_statements( ys : Array[Cirru], options : CirruWriterOptions @@ -309,7 +327,7 @@ fn generate_statements( zs } -/// format Cirru code, use options to control `use_inline` option +///| format Cirru code, use options to control `use_inline` option pub fn format( xs : Array[Cirru], options : CirruWriterOptions