diff --git a/tools/lsp/squirrel/grammar/reasonligo/grammar.js b/tools/lsp/squirrel/grammar/reasonligo/grammar.js index 4ba1ffcc7..bfd4ec0b4 100644 --- a/tools/lsp/squirrel/grammar/reasonligo/grammar.js +++ b/tools/lsp/squirrel/grammar/reasonligo/grammar.js @@ -1,6 +1,4 @@ const PREC = { - - CALL: 300000000, OR: 0, AND: 1, COMPARE: 3, @@ -9,13 +7,9 @@ const PREC = { MINUS: 6, MUL: 7, DIV: 7, - ATTR: 1, TYPE: 101, LET: 100, - EXPR: 100000000, - CONSTR: 100000, - LAM: 1000, }; const OPS = [ @@ -58,367 +52,25 @@ module.exports = grammar({ name: 'ReasonLigo', word: $ => $.Keyword, - extras: $ => [$.oneline_comment, $.block_comment, /\s/], + extras: $ => [$.oneline_comment, $.block_comment, /\s/, $.attr], - conflicts: $ => [ - [$._fun_type, $.type_application], - [$._pattern, $.tuple_pattern], - [$._expr], // TODO: left-precendence is used for tuple_expr, right for nested `let`s - [$._exprf], - - [$.tuple_expr, $.parameters], - [$.record_field, $._accessor], // TODO - [$.variant], // TODO: some alien stuff - [$.sum_type], // TODO: fix in `let_declaration`. - [$.bracket_block], // TODO: same as $.lambda_body - [$.type_decl], - [$.lambda], - [$._instruction, $._expr], // switch_instr - [$._functional_block, $.bracket_block], // TODO: remove - [$.list_access], // TODO: remove - [$.list_access, $._ident], // TODO - [$.record_field, $._ident], // TODO - [$._core_pattern, $._expr], //TODO: remove as soon as possible - [$.lambda_call], // TODO: remove - [$.lambda_call, $.binary_call], - [$._expr, $.bracket_block], // TODO - [$.lambda_call, $.parameters], // TODO - [$["-"], $.negate], // unary vs binary calls - - [$.parameters, $.annot_expr], // TODO - [$.type_tuple, $._core_type], - - [$._pattern, $.annot_pattern], // TODO: constr (pat) case - [$.annot_expr, $._type_annotation], - [$.annot_expr, $.lambda_call], - [$.annot_expr, $._functional_block], - - // TODO: those are produced in conflicts of `fun_call` and `expr` in bracket blocks - [$.annot_expr, $._exprf], - [$.lambda_call, $._exprf], - [$.bracket_block, $._exprf], - [$._functional_block, $._exprf], - [$.tuple_expr, $._exprf], - [$._annot_fun_call, $._exprf], - ], + conflicts: $ => + [[$._expr_term, $._pattern] + , [$._expr_term, $.var_pattern] + , [$.Name, $.TypeName] + , [$._expr_term, $.module_name] + , [$.annot_pattern, $.let_declaration] + , [$.lambda, $.tuple_pattern] + , [$._expr_term, $.nullary_constr_pattern] + , [$.list, $.list_pattern] + , [$._expr_term, $.lhs] + , [$._field_name, $.lhs] + , [$._expr_term, $.capture] + , [$.type_string, $._literal] + ], rules: { - contract: $ => sepBy(optional(';'), field("declaration", $._declaration)), - - _expr: $ => - prec(PREC.EXPR, - seq( - choice( - $.lambda_call, - $.tuple_expr, - $._literal, - // $.fun_call, - $.constructor_call, - $.unary_call, - $.binary_call, - $.annot_expr, - $.list_expr, - $.record_expr, - $._ref, - $._ident, - $.switch_instr, - ), - ), - ), - - // TODO: workaround to move `fun_call` out of `expr` needed in bracket blocks - _exprf: $ => choice($.fun_call, $._expr), - - _annot_expr: $ => - par($.annot_expr), - - annot_expr: $ => - seq( - field("subject", $._expr), - ':', - field("type", $._type_expr), - ), - - // TODO: same as tuple_pattern - // TODO: to annotate expression we do not need to enclose it in brackets - // TODO: possible ((a : p) : q, b) - tuple_expr: $ => - par(sepBy1(',', - seq( - field("element", choice( - $.annot_expr, - $.fun_call, - $._expr, - )), - ) - )), - - constructor_call: $ => - prec(PREC.CONSTR, - seq( - field("constructor", - choice( - $._constr, - $.module_qualified, - ), - ), - field("parameters", $.parameters), - ), - ), - - lambda_call: $ => - seq( - par(field("lambda", $.lambda)), - repeat1( - choice( - field("arguments", $._expr), - par(field("arguments", $.lambda)) - ) - ), // TODO: workaround to move lambda out of expr - ), - - fun_call: $ => - prec.right(PREC.CALL, - seq( - field("f", $.Name), // TODO: may be qualified - field("arguments", $.parameters), - ) - ), - - binary_call: $ => choice( - ...OPS - .map(([op, precendence]) => - prec.left(precendence, seq( - field("left", $._exprf), - field("op", $[op]), - field("right", $._exprf), - )) - ) - ), - - // Workaround to make operators to be instructions as well - // so that they won't be stripped when naming them as fields - ...OPS.reduce( - (acc, [e, _]) => ({ ...acc, [e]: $ => seq(e) }), {} - ), - - unary_call: $ => prec.right(8, - seq( - field("negate", $.negate), - field("arg", $._exprf) - ) - ), - - negate: $ => choice('-', '!'), - - // TODO: refactor - call: $ => - prec.left(1, - choice( - seq($.call, par($._expr)), - par($._expr), - ), - ), - - switch_instr: $ => - prec.left(0, // TODO - seq( - 'switch', - choice( - field('subject', $.Name), - par(field('subject', $._exprf)), - ), - block(seq( - optional('|'), - sepBy1('|', field('case', $.alt)), - )), - ), - ), - - // TODO: it may parse expr with ';' attached to the end - alt: $ => - seq( - field("pattern", $._pattern), - '=>', - field("body", $._functional_block), - optional(';'), - ), - - - _literal: $ => - choice( - $.Nat, - $.Int, - $.Bool, - $.Tez, - $.String, - $.Bytes, - $.Unit, - $.Nil, - $.wildcard, - ), - - record_expr: $ => - seq( - block(seq( - sepBy1(',', field("assignment", choice( - $.spread, - $.record_field, - ))), - optional($._ident), // TODO: not need to be here - )) - ), - - spread: $ => seq( - '...', - field("name", $._ident), // TODO: may be possible expression - ), - - record_field: $ => - seq( - field("name", sepBy1('.', $.Name)), - ':', - field("value", $._expr), - ), - - _statement: $ => choice( - $._instruction, - ), - - _instruction: $ => - prec(PREC.EXPR, choice( - $.conditional, - $.switch_instr, - $.let_declaration, - )), - - lambda: $ => - seq( - field("lambda_head", seq( - field("arguments", $.parameters), - optional(seq(":", - field("lambda_type", - choice($._core_type, $.type_tuple), - ), - )) - )), - '=>', - field("lambda_body", $._functional_block) - ), - - parameters: $ => - par( - sepBy(',', field("parameter", seq( - choice($._exprf, $.lambda), // TODO: workaround to move lambda our of expr - optional($._type_annotation), // TODO: move it somewhere - ))) - ), - - _pattern: $ => - choice( - $.cons_pattern, - $.annot_pattern, - $._core_pattern, - ), - - cons_pattern: $ => - brackets( - seq( - field("head", $._core_pattern), - ',', - field("tail", choice( - $.spread, - $._pattern, - )), - ) - ), - - annot_pattern: $ => - par( - seq( - field("subject", $._core_pattern), - ':', - field("type", $._type_expr), - ) - ), - - _core_pattern: $ => - prec.right(PREC.CONSTR, - seq( - choice( - $.constr_pattern, - $.tuple_pattern, - $._literal, - $.Name, - ), - ) - ), - - tuple_pattern: $ => - par(tuple(field("element", $._pattern))), - - constr_pattern: $ => - prec.right(PREC.CONSTR, // TODO: left precendence fails - seq( - field("constr", $._constr), - optional( - opar( - field("arguments", $._pattern) - ), - )), - ), - - list_expr: $ => brackets( - sepBy(',', field("element", choice( - $.spread, - $._expr, - ))) - ), - - - conditional: $ => - prec.left(PREC.LET, - seq( - 'if', - par(field("selector", $._expr)), - field("then", $.bracket_block), - optional(seq( - 'else', - field("else", $.bracket_block), - )), - ), - ), - - _ref: $ => - choice( - $.module_qualified, - $.struct_qualified, - $._constr, - $.list_access, - ), - - module_qualified: $ => - seq( - field("module", $._constr), - nseq(seq('.', field("method", $.Name))), // TODO: capital letters - ), - - // TODO: may be the same as `list_access` - struct_qualified: $ => - seq( - field("struct", $.Name), - nseq(seq('.', field("method", $._accessor))), - ), - - _accessor: $ => choice($.Name, $.Int), - - list_access: $ => - // prec.left(8, - seq( - field("name", $.Name), - repeat1(brackets(field("indexes", $.Int))), - // ), - ), + contract: $ => sepBy1(optional(';'), field("declaration", $._declaration)), _declaration: $ => field("declaration", @@ -426,17 +78,212 @@ module.exports = grammar({ $.type_decl, $.let_declaration, $.include, - $.attr_decl, ) ), - attr_decl: $ => - prec.left(PREC.ATTR, - nseq(brackets( - seq('@', field("name", $.Name)) - )) + //// EXPRESSIONS /////////////////////////////////////////////////////////// + + let_declaration: $ => prec.left(PREC.LET, seq( + 'let', + optional(field("rec", $.rec)), + sepBy1(',', field("binding", $._pattern)), + optional(seq( + ':', + field("type", $._type_expr) + )), + '=', + field("value", $._expr), + )), + + var_pattern: $ => field("var", $.Name), + + fun_type: $ => + prec.right(8, + seq( + field("domain", $._type_expr), + '=>', + field("codomain", $._type_expr), + ), ), + module_TypeName: $ => + seq( + $.module_name, + '.', + $.TypeName, + ), + + _expr: $ => choice( + $.lambda, + $.indexing, + $.binary_call, + $.unary_call, + $._expr_term, + $.apply, + $.Some_call, + ), + + Some_call: $ => prec.right(10, seq( + field("some", $.Some), + field("argument", $._expr), + )), + + apply: $ => prec.left(20, seq( + field("function", $._expr), + par(sepBy(',', field("argument", $._expr))), + )), + + _expr_term: $ => choice( + $.block, + $.tuple, + $.list, + $._literal, + $.Name, + $.Name_Capital, + $.qualified_name, + $.if, + $.switch, + $.record, + ), + + record: $ => block( + seq( + // TODO: possible multiple spreads + optional(seq(field("spread", $.spread), ',')), + sepBy(',', field("assignment", $._record_field)), + ), + ), + + _record_field: $ => choice( + $.record_field, + $.capture, + ), + + capture: $ => $.Name, + + record_field: $ => seq( + field("name", $.lhs), + ':', + field("value", $._expr), + ), + + lhs: $ => seq( + optional(seq(field("name", $.Name), '.')), + field("callee", $.Name), + ), + + list: $ => brackets( + sepBy(',', field("element", $._spread_expr)), + ), + + _spread_expr: $ => choice( + $._expr, + $.spread, + ), + + spread: $ => seq( + '...', + $._expr, + ), + + if: $ => seq( + 'if', + field("selector", $._expr), + field("then", $.block), + optional(seq( + 'else', + field('else', $.block), + )) + ), + + switch: $ => seq( + 'switch', + field("subject", $._expr_term), + block(seq( + optional('|'), + sepBy('|', field("alt", $.alt)), + )) + ), + + alt: $ => seq( + field("pattern", $._pattern), + '=>', + field("expr", $._expr), + optional(';'), + ), + + qualified_name: $ => seq( + field("expr", $._expr), + '.', + field("name", $.Name), + ), + + binary_call: $ => choice( + ...OPS + .map(([op, precendence]) => + prec.right(precendence, seq( + field("left", $._expr), + field("op", $[op]), + field("right", $._expr), + )) + ) + ), + + // Workaround to make operators to be statements as well + // so that they won't be stripped when naming them as fields + ...OPS.reduce( + (acc, [e, _]) => ({ ...acc, [e]: $ => seq(e) }), {} + ), + + unary_call: $ => prec.right(8, seq(field("negate", $.negate), field("arg", $._expr_term))), + + negate: $ => choice('-', '!'), + + indexing: $ => prec.right(12, seq( + field("box", $._expr), + brackets( + field("index", $._expr), + ) + )), + + block: $ => prec(1, block( + seq( + sepBy(';', field("statement", $._statement)), + optional(';'), + ) + )), + + _statement: $ => prec(1, choice( + $.let_declaration, + $._expr, + )), + + tuple: $ => + par(sepBy1(',', field("item", $._annot_expr))), + + _annot_expr: $ => choice( + $.annot_expr, + $._expr, + ), + + annot_expr: $ => seq( + field("subject", $._expr), + ':', + field("type", $._type_expr), + ), + + lambda: $ => prec.right(12, seq( + par(sepBy(',', field("argument", $._pattern))), + optional(seq( + ':', + field("type", $._type_expr), + )), + '=>', + field("body", $._expr), + )), + + //// TYPES ///////////////////////////////////////////////////////////////// + type_decl: $ => seq( 'type', @@ -446,70 +293,84 @@ module.exports = grammar({ ), _type_expr: $ => - choice( - $._fun_type, - $.sum_type, - $.record_type, - ), - - _fun_type: $ => choice( $.fun_type, $._core_type, $.type_tuple, + $.sum_type, + $.record_type, + $.type_string, ), + michelson_tuple: $ => seq( + '(', + $._type_expr, + ',', + $.String, + ',', + $._type_expr, + ',', + $.String, + ')', + ), + fun_type: $ => - seq( - field("domain", choice($._core_type, $.type_tuple)), - '=>', - field("codomain", $._fun_type), + prec.right(8, + seq( + field("domain", $._type_expr), + '=>', + field("codomain", $._type_expr), + ), ), _core_type: $ => choice( $.type_application, $.TypeName, - $.type_string, - $.module_TypeName, + // $.module_TypeName, ), module_TypeName: $ => seq( - $.module_name, + field("module", $.module_name), '.', - $.TypeName, + field("type", $.TypeName), ), type_application: $ => seq( field("functor", $._core_type), - par(sepBy(',', field("parameter", $._type_expr))), + field("arguments", $._type_arguments), ), + _type_arguments: $ => choice( + // $.michelson_tuple, + par(sepBy(',', field("argument", $._type_expr))), + ), + type_string: $ => $.String, type_tuple: $ => par(sepBy1(',', field("element", $._type_expr))), sum_type: $ => - seq( - optional('|'), - sepBy1('|', field("variant", $.variant)), + prec.left(8, + seq( + optional('|'), + sepBy1('|', field("variant", $.variant)), + ), ), variant: $ => - seq( - field("constructor", $._constr), - optional(par(field("arguments", $._fun_type))), + prec.left(8, + seq( + field("constructor", $.Name_Capital), + optional(par(field("arguments", $._type_expr))), + ), ), record_type: $ => - seq( - '{', - sepBy(',', field("field", $.field_decl)), - '}', - ), + block(sepBy(',', field("field", $.field_decl))), field_decl: $ => seq( @@ -518,115 +379,75 @@ module.exports = grammar({ field("field_type", $._type_expr), ), - te: $ => choice( - $.lambda, - $._expr, + //// PATTERNS ////////////////////////////////////////////////////////////// + + _pattern: $ => + choice( + $.tuple_pattern, + $._literal, + $.var_pattern, + $.annot_pattern, + $.wildcard, + $.unary_constr_pattern, + $.nullary_constr_pattern, + $.list_pattern, + ), + + nullary_constr_pattern: $ => seq( + field("constructor", $.Name_Capital), ), - _functional_block: $ => - choice( - $._statement, - $._expr, - $.fun_call, - $.bracket_block, - ), + unary_constr_pattern: $ => prec(1, seq( + field("constructor", $.Name_Capital), + field("arg", $._pattern), + )), - _annot_fun_call: $ => // Workaround used only in bracket blocks - par(seq( - $.fun_call, - ':', - $._type_expr, - )), - - bracket_block: $ => - prec.right(1000000, // TODO: precendence - block( - choice( - seq( - sepBy(';', field("statement", choice( - $.constructor_call, - seq( - optional($.attr_decl), - $._statement, - ), - $.fun_call, - // $._expr, // TODO: use only `fun_call` from there, somewhat fails if called directly - ))), - optional(seq( - opar( - field("return", - choice( - $._expr, - seq( // TODO: maybe not all returned function calls need to be annotated - $.fun_call, - ':', - $._type_expr, // TODO: maybe we'll need to annotate fields here, but so far we just return multiple 'return's - ) - ) - ) - ), - optional(';'), - ))), - $.bracket_block, - ), // TODO conflict: _group bracket_block - ) - ), - - let_declaration: $ => - prec.left(PREC.LET, - seq( - 'let', - optional($.rec), - field("binding", choice( - sepBy1(',', $._core_pattern), - )), - optional(seq(':', field("type", $._type_expr))), - '=', - field("let_value", - choice( - $.lambda, - $._functional_block, - ), - ), - ) - ), - - _type_annotation: $ => - seq( - ':', - field("type", $._type_expr) - ), - - pattern_term: $ => - choice( - $.Name, - $.pattern_grouped, - ), - - pattern_grouped: $ => - seq( + constr_pattern: $ => seq( + field("ctor", $.Name_Capital), + optional(seq( '(', - $._core_pattern, - optional($._type_annotation), + sepBy(',', field("arg", $._pattern)), ')', - ), + )), + ), - pattern_list: $ => list__($._pattern), - pattern_constant: $ => + annot_pattern: $ => seq( + field("subject", $._pattern), + ':', + field("type", $._type_expr), + ), + + tuple_pattern: $ => prec(13, par( + sepBy1(',', field("pattern", $._pattern)), + )), + + list_pattern: $ => brackets( + sepBy(',', field("pattern", $._spread_pattern)), + ), + + _spread_pattern: $ => choice( + $.spread_pattern, + $._pattern, + ), + + spread_pattern: $ => seq( + '...', + field("expr", $._pattern), + ), + + _literal: $ => choice( $.Nat, + $.Int, + $.Bool, + $.Tez, $.String, $.Bytes, - $.Int, + $.Unit, + $.Nil, + $.None, ), - pattern_tuple: $ => sepBy1(',', $._construct), - - _construct: $ => - choice( - seq($._constr, nseq($.pattern_term)), - par($.pattern_term), - ), /////////////////////////////////////////// @@ -635,8 +456,6 @@ module.exports = grammar({ struct_name: $ => $.Name, var: $ => $.Name, module_name: $ => $.Name_Capital, - _constr: $ => $.Name_Capital, - // TODO: remove _ident: $ => $.Name, comment: $ => choice( @@ -676,7 +495,8 @@ module.exports = grammar({ skip: $ => 'skip', rec: $ => 'rec', wildcard: $ => '_', + rec: $ => 'rec', - attr: $ => seq('[@@', $.Name, ']'), + attr: $ => seq('[@', $.Name, ']'), } }); \ No newline at end of file diff --git a/tools/lsp/squirrel/src/AST/Camligo/Parser.hs b/tools/lsp/squirrel/src/AST/Camligo/Parser.hs index 62f0baf75..067302a9e 100644 --- a/tools/lsp/squirrel/src/AST/Camligo/Parser.hs +++ b/tools/lsp/squirrel/src/AST/Camligo/Parser.hs @@ -112,7 +112,7 @@ recognise = descent (\_ -> error . show . pp) $ map usingScope -- -- Expr , Descent do boilerplate $ \case - "fun_app" -> Apply <$> field "f" <*> field "x" + "fun_app" -> Apply <$> field "f" <*> fields "x" "index_accessor" -> ListAccess <$> field "box" <*> fields "field" "rec_expr" -> RecordUpd <$> field "subject" <*> fields "field" "rec_literal" -> Record <$> fields "field" diff --git a/tools/lsp/squirrel/src/AST/Pascaligo/Parser.hs b/tools/lsp/squirrel/src/AST/Pascaligo/Parser.hs index c0b88e423..45ed7c400 100644 --- a/tools/lsp/squirrel/src/AST/Pascaligo/Parser.hs +++ b/tools/lsp/squirrel/src/AST/Pascaligo/Parser.hs @@ -71,11 +71,11 @@ recognise = descent (\_ -> error . show . pp) $ map usingScope , Descent do boilerplate \case "let_expr" -> Let <$> field "locals" <*> field "body" - "fun_call" -> Apply <$> field "f" <*> field "arguments" - "par_call" -> Apply <$> field "f" <*> field "arguments" - "projection_call" -> Apply <$> field "f" <*> field "arguments" - "Some_call" -> Apply <$> field "constr" <*> field "arguments" - "constr_call" -> Apply <$> field "constr" <*> field "arguments" + "fun_call" -> Apply <$> field "f" <*> fields "arguments" + "par_call" -> Apply <$> field "f" <*> fields "arguments" + "projection_call" -> Apply <$> field "f" <*> fields "arguments" + "Some_call" -> Apply <$> field "constr" <*> fields "arguments" + "constr_call" -> Apply <$> field "constr" <*> fields "arguments" "arguments" -> Tuple <$> fields "argument" "unop" -> UnOp <$> field "negate" <*> field "arg" "binop" -> BinOp <$> field "arg1" <*> field "op" <*> field "arg2" @@ -183,7 +183,7 @@ recognise = descent (\_ -> error . show . pp) $ map usingScope -- VarDecl , Descent do boilerplate \case - "param_decl" -> Decl <$> field "access" <*> field "name" <*> field "type" + "param_decl" -> Decl <$> field "access" <*> field "name" <*> fieldOpt "type" _ -> fallthrough -- Mutable diff --git a/tools/lsp/squirrel/src/AST/Reasonligo/Parser.hs b/tools/lsp/squirrel/src/AST/Reasonligo/Parser.hs index 9ea74f5d2..f4c8ba355 100644 --- a/tools/lsp/squirrel/src/AST/Reasonligo/Parser.hs +++ b/tools/lsp/squirrel/src/AST/Reasonligo/Parser.hs @@ -17,6 +17,9 @@ import Product -- example = "./contracts/variant.religo" -- example = "./contracts/amount.religo" -- example = "./contracts/multisig.religo" +-- example = "./contracts/arithmetic.religo" +-- example = "./contracts/lambda.religo" +-- example = "./contracts/id.religo" -- example = "../../../src/test/contracts/FA1.2.religo" -- example = "../../../src/test/contracts/multisig.religo" -- example = "../../../src/test/contracts/lambda.religo" @@ -32,14 +35,11 @@ import Product -- example = "./contracts/attributes.religo" -- example = "./contracts/lambda.religo" -- example = "./contracts/arithmetic.religo" --- example = "./contracts/letin.religo" +-- example = "./contracts/FA2.religo" --- raw :: IO () --- raw = toParseTree (Path example) --- >>= print . pp - --- sample :: IO () --- sample = toParseTree (Path example) +-- sample''' :: IO () +-- sample''' +-- = toParseTree (Path example) -- >>= runParserM . recognise -- >>= print . pp . fst @@ -51,50 +51,46 @@ recognise = descent (\_ -> error . show . pp) $ map usingScope "contract" -> RawContract <$> fields "declaration" _ -> fallthrough - -- ReasonExpr - , Descent do - boilerplate $ \case - "bracket_block" -> Block <$> fields "statement" <*> fieldOpt "return" - _ -> fallthrough - - -- Expr , Descent do boilerplate $ \case - "fun_call" -> Apply <$> field "f" <*> field "arguments" - "lambda_call" -> Apply <$> field "lambda" <*> field "arguments" -- TODO: maybe a separate apply? - "arguments" -> Tuple <$> fields "argument" - "unary_call" -> UnOp <$> field "negate" <*> field "arg" - "binary_call" -> BinOp <$> field "left" <*> field "op" <*> field "right" - "constructor_call" -> Apply <$> field "constructor" <*> field "parameters" - "block" -> Seq <$> fields "statement" - "list_expr" -> List <$> fields "element" - "list_access" -> ListAccess <$> field "name" <*> fields "indexes" - "annot_expr" -> Annot <$> field "subject" <*> field "type" - "conditional" -> If <$> field "selector" <*> field "then" <*> fieldOpt "else" - "record_expr" -> Record <$> fields "assignment" - "tuple_expr" -> Tuple <$> fields "element" - - "switch_instr" -> Case <$> field "subject" <*> fields "case" - "lambda" -> Lambda <$> fields "arguments" <*> fieldOpt "lambda_type" <*> field "lambda_body" - _ -> fallthrough + "unary_call" -> UnOp <$> field "negate" <*> field "arg" + "binary_call" -> BinOp <$> field "left" <*> field "op" <*> field "right" + "Some_call" -> Apply <$> field "some" <*> fields "argument" + "apply" -> Apply <$> field "function" <*> fields "argument" + "block" -> Seq <$> fields "statement" + "list" -> List <$> fields "element" + "indexing" -> ListAccess <$> field "box" <*> fields "index" + "annot_expr" -> Annot <$> field "subject" <*> field "type" + "if" -> If <$> field "selector" <*> field "then" <*> fieldOpt "else" + -- TODO: possible support for multiple spreads + "record" -> Record <$> fields "assignment" + "tuple" -> Tuple <$> fields "item" + "switch" -> Case <$> field "subject" <*> fields "alt" + "lambda" -> Lambda <$> fields "argument" <*> fieldOpt "type" <*> field "body" + _ -> fallthrough -- Pattern , Descent do boilerplate $ \case - "constr_pattern" -> IsConstr <$> field "constr" <*> fieldOpt "arguments" - "tuple_pattern" -> IsTuple <$> fields "element" - "cons_pattern" -> IsCons <$> field "head" <*> field "tail" - "annot_pattern" -> IsAnnot <$> field "subject" <*> field "type" - _ -> fallthrough + "tuple_pattern" -> IsTuple <$> fields "pattern" + "annot_pattern" -> IsAnnot <$> field "subject" <*> field "type" + "list_pattern" -> IsList <$> fields "pattern" + "var_pattern" -> IsVar <$> field "var" + "wildcard" -> return IsWildcard + "nullary_constr_pattern" -> IsConstr <$> field "constructor" <*> return Nothing + "unary_constr_pattern" -> IsConstr <$> field "constructor" <*> fieldOpt "arg" + "spread_pattern" -> IsSpread <$> field "expr" + _ -> fallthrough -- Alt , Descent do boilerplate $ \case - "alt" -> Alt <$> field "pattern" <*> field "body" + "alt" -> Alt <$> field "pattern" <*> field "expr" _ -> fallthrough -- Record fields + -- TODO: capture and record , Descent do boilerplate $ \case "record_field" -> FieldAssignment <$> field "name" <*> field "value" @@ -127,8 +123,8 @@ recognise = descent (\_ -> error . show . pp) $ map usingScope , Descent do boilerplate $ \case - "module_qualified" -> QualifiedName <$> field "module" <*> fields "method" - "struct_qualified" -> QualifiedName <$> field "struct" <*> fields "method" + "qualified_name" -> QualifiedName <$> field "expr" <*> fields "name" + "lhs" -> QualifiedName <$> field "callee" <*> fields "name" _ -> fallthrough -- Literal @@ -144,24 +140,12 @@ recognise = descent (\_ -> error . show . pp) $ map usingScope -- Declaration , Descent do boilerplate $ \case - -- TODO: Current `Let` in ast is untyped - "let_declaration" -> Var <$> field "binding" <*> fieldOpt "let_type" <*> field "let_value" + -- TODO: We forget "rec" field in let + "let_declaration" -> Var <$> field "binding" <*> fieldOpt "type" <*> field "value" "type_decl" -> TypeDecl <$> field "type_name" <*> field "type_value" "attr_decl" -> Attribute <$> field "name" _ -> fallthrough - -- Parameters - , Descent do - boilerplate $ \case - "parameters" -> Parameters <$> fields "parameter" - _ -> fallthrough - - -- VarDecl - , Descent do - boilerplate $ \case - "param_decl" -> Decl <$> field "access" <*> field "name" <*> field "type" - _ -> fallthrough - -- Name , Descent do boilerplate' $ \case @@ -174,12 +158,19 @@ recognise = descent (\_ -> error . show . pp) $ map usingScope , Descent do boilerplate $ \case "fun_type" -> TArrow <$> field "domain" <*> field "codomain" - "type_application" -> TApply <$> field "functor" <*> fields "parameter" + "type_application" -> TApply <$> field "functor" <*> fields "argument" "type_tuple" -> TTuple <$> fields "element" "record_type" -> TRecord <$> fields "field" "sum_type" -> TSum <$> fields "variant" _ -> fallthrough + -- Michelson pair types + , Descent do + boilerplate' $ \case + ("type_string", i) -> return $ TString i + _ -> fallthrough + + -- Variant , Descent do boilerplate $ \case diff --git a/tools/lsp/squirrel/src/AST/Scope.hs b/tools/lsp/squirrel/src/AST/Scope.hs index b2d5483e3..3e677ec6b 100644 --- a/tools/lsp/squirrel/src/AST/Scope.hs +++ b/tools/lsp/squirrel/src/AST/Scope.hs @@ -358,7 +358,7 @@ instance Collectable xs => Scoped (Product xs) CollectM (LIGO (Product xs)) Bind _ -> skip instance Collectable xs => Scoped (Product xs) CollectM (LIGO (Product xs)) VarDecl where - after r (Decl _ name ty) = def name (Just ty) Nothing (getElem r) + after r (Decl _ name ty) = def name ty Nothing (getElem r) instance Scoped a CollectM (LIGO a) Mutable instance Scoped a CollectM (LIGO a) Type diff --git a/tools/lsp/squirrel/src/AST/Skeleton.hs b/tools/lsp/squirrel/src/AST/Skeleton.hs index a89ba2b61..6c7392f18 100644 --- a/tools/lsp/squirrel/src/AST/Skeleton.hs +++ b/tools/lsp/squirrel/src/AST/Skeleton.hs @@ -78,7 +78,7 @@ data Parameters it deriving stock (Functor, Foldable, Traversable) data VarDecl it - = Decl it it it -- ^ (Mutable) (Name) (Type) + = Decl it it (Maybe it) -- ^ (Mutable) (Name) (Type) deriving (Show) via PP (VarDecl it) deriving stock (Functor, Foldable, Traversable) @@ -95,7 +95,8 @@ data Type it | TVar it -- ^ (Name) | TSum [it] -- ^ [Variant] | TProduct [it] -- ^ [Type] - | TApply it [it] -- (Name) [Type] + | TApply it [it] -- ^ (Name) [Type] + | TString Text -- ^ (TString) | TTuple [it] | TOr it it it it | TAnd it it it it @@ -115,7 +116,7 @@ data TField it -- | TODO: break onto smaller types? Literals -> Constant; mapOps; mmove Annots to Decls. data Expr it = Let it it -- Declaration Expr - | Apply it it -- (Expr) [Expr] + | Apply it [it] -- (Expr) [Expr] | Constant it -- (Constant) | Ident it -- (QualifiedName) | BinOp it it it -- (Expr) Text (Expr) @@ -191,6 +192,7 @@ data Pattern it | IsCons it it -- (Pattern) (Pattern) | IsAnnot it it -- (Pattern) (Type) -- Semantically `Var` | IsWildcard + | IsSpread it -- (Name) | IsList [it] -- [Pattern] | IsTuple [it] -- [Pattern] deriving (Show) via PP (Pattern it) @@ -275,7 +277,7 @@ instance Pretty1 Parameters where instance Pretty1 VarDecl where pp1 = \case - Decl mutability name ty -> sexpr "decl" [mutability, name, ty] + Decl mutability name ty -> sexpr "decl" [mutability, name, pp ty] instance Pretty1 Mutable where pp1 = \case @@ -290,6 +292,7 @@ instance Pretty1 Type where TSum variants -> sexpr "SUM" variants TProduct elements -> sexpr "PROD" elements TApply f xs -> sop f "$" xs + TString t -> pp t TTuple xs -> sexpr "TUPLE" xs TOr l n r m -> sexpr "OR" [l, n, r, m] TAnd l n r m -> sexpr "AND" [l, n, r, m] @@ -305,7 +308,7 @@ instance Pretty1 ReasonExpr where instance Pretty1 Expr where pp1 = \case Let decl body -> sexpr "let" [decl, body] - Apply f xs -> sexpr "apply" [f, xs] + Apply f xs -> sexpr "apply" (f : xs) Constant constant -> constant Ident qname -> qname BinOp l o r -> sop l (ppToText o) [r] @@ -374,6 +377,7 @@ instance Pretty1 Pattern where IsCons h t -> sop h "::?" [t] IsAnnot s t -> sexpr "type?" [s, t] IsWildcard -> "_?" + IsSpread n -> "..." <.> pp n IsList l -> sexpr "list?" l IsTuple t -> sexpr "tuple?" t