Removed entrypoint and storage as keywords.

Bug fix: `n-1` was scanned as `n` and `-1`, which was rejected by
a style constraint.

I removed useless style constraints in the lexer.

I removed dead code in `pascaligo.ml`.

I added my first draft for the reference manual of PascaLIGO: DO
NOT EDIT. Edit the website instead.

About the bug fix: This was an awkward attempt at rejecting at
lexing time negative integer literals whose sign is separated
from the digits, like `- 1`. The fix was simple: remove the
`integer` regular expression and use `natural`.
This commit is contained in:
Christian Rinderknecht 2019-09-26 16:35:16 +02:00
parent 4b4698d1f0
commit 10469818c1
14 changed files with 1395 additions and 257 deletions

View File

@ -17,5 +17,4 @@ $HOME/git/ligo/src/parser/shared/Markup.ml
$HOME/git/ligo/src/parser/shared/Markup.mli
$HOME/git/ligo/src/parser/shared/Utils.mli
$HOME/git/ligo/src/parser/shared/Utils.ml
$HOME/git/ligo/src/parser/shared/Version.ml
Stubs/Simple_utils.ml

View File

@ -49,7 +49,6 @@ type kwd_contains = Region.t
type kwd_down = Region.t
type kwd_else = Region.t
type kwd_end = Region.t
type kwd_entrypoint = Region.t
type kwd_fail = Region.t
type kwd_for = Region.t
type kwd_from = Region.t
@ -71,7 +70,6 @@ type kwd_remove = Region.t
type kwd_set = Region.t
type kwd_skip = Region.t
type kwd_step = Region.t
type kwd_storage = Region.t
type kwd_then = Region.t
type kwd_to = Region.t
type kwd_type = Region.t
@ -219,7 +217,6 @@ and type_tuple = (type_expr, comma) nsepseq par reg
and lambda_decl =
FunDecl of fun_decl reg
| ProcDecl of proc_decl reg
| EntryDecl of entry_decl reg
and fun_decl = {
kwd_function : kwd_function;
@ -245,36 +242,8 @@ and proc_decl = {
terminator : semi option
}
and entry_decl = {
kwd_entrypoint : kwd_entrypoint;
name : variable;
param : entry_params;
colon : colon;
ret_type : type_expr;
kwd_is : kwd_is;
local_decls : local_decl list;
block : block reg;
kwd_with : kwd_with;
return : expr;
terminator : semi option
}
and parameters = (param_decl, semi) nsepseq par reg
and entry_params = (entry_param_decl, semi) nsepseq par reg
and entry_param_decl =
EntryConst of param_const reg
| EntryVar of param_var reg
| EntryStore of storage reg
and storage = {
kwd_storage : kwd_storage;
var : variable;
colon : colon;
storage_type : type_expr
}
and param_decl =
ParamConst of param_const reg
| ParamVar of param_var reg

View File

@ -33,7 +33,6 @@ type kwd_contains = Region.t
type kwd_down = Region.t
type kwd_else = Region.t
type kwd_end = Region.t
type kwd_entrypoint = Region.t
type kwd_fail = Region.t
type kwd_for = Region.t
type kwd_from = Region.t
@ -55,7 +54,6 @@ type kwd_remove = Region.t
type kwd_set = Region.t
type kwd_skip = Region.t
type kwd_step = Region.t
type kwd_storage = Region.t
type kwd_then = Region.t
type kwd_to = Region.t
type kwd_type = Region.t
@ -203,7 +201,6 @@ and type_tuple = (type_expr, comma) nsepseq par reg
and lambda_decl =
FunDecl of fun_decl reg
| ProcDecl of proc_decl reg
| EntryDecl of entry_decl reg
and fun_decl = {
kwd_function : kwd_function;
@ -229,36 +226,8 @@ and proc_decl = {
terminator : semi option
}
and entry_decl = {
kwd_entrypoint : kwd_entrypoint;
name : variable;
param : entry_params;
colon : colon;
ret_type : type_expr;
kwd_is : kwd_is;
local_decls : local_decl list;
block : block reg;
kwd_with : kwd_with;
return : expr;
terminator : semi option
}
and parameters = (param_decl, semi) nsepseq par reg
and entry_params = (entry_param_decl, semi) nsepseq par reg
and entry_param_decl =
EntryConst of param_const reg
| EntryVar of param_var reg
| EntryStore of storage reg
and storage = {
kwd_storage : kwd_storage;
var : variable;
colon : colon;
storage_type : type_expr
}
and param_decl =
ParamConst of param_const reg
| ParamVar of param_var reg

File diff suppressed because it is too large Load Diff

View File

@ -79,7 +79,6 @@ type t =
| Down of Region.t (* "down" *)
| Else of Region.t (* "else" *)
| End of Region.t (* "end" *)
| Entrypoint of Region.t (* "entrypoint" *)
| Fail of Region.t (* "fail" *)
| For of Region.t (* "for" *)
| From of Region.t (* "from" *)
@ -101,7 +100,6 @@ type t =
| Set of Region.t (* "set" *)
| Skip of Region.t (* "skip" *)
| Step of Region.t (* "step" *)
| Storage of Region.t (* "storage" *)
| Then of Region.t (* "then" *)
| To of Region.t (* "to" *)
| Type of Region.t (* "type" *)

View File

@ -77,7 +77,6 @@ type t =
| Down of Region.t (* "down" *)
| Else of Region.t (* "else" *)
| End of Region.t (* "end" *)
| Entrypoint of Region.t (* "entrypoint" *)
| Fail of Region.t (* "fail" *)
| For of Region.t (* "for" *)
| From of Region.t (* "from" *)
@ -99,7 +98,6 @@ type t =
| Set of Region.t (* "set" *)
| Skip of Region.t (* "skip" *)
| Step of Region.t (* "step" *)
| Storage of Region.t (* "storage" *)
| Then of Region.t (* "then" *)
| To of Region.t (* "to" *)
| Type of Region.t (* "type" *)
@ -210,7 +208,6 @@ let proj_token = function
| Down region -> region, "Down"
| Else region -> region, "Else"
| End region -> region, "End"
| Entrypoint region -> region, "Entrypoint"
| Fail region -> region, "Fail"
| For region -> region, "For"
| From region -> region, "From"
@ -232,7 +229,6 @@ let proj_token = function
| Set region -> region, "Set"
| Skip region -> region, "Skip"
| Step region -> region, "Step"
| Storage region -> region, "Storage"
| Then region -> region, "Then"
| To region -> region, "To"
| Type region -> region, "Type"
@ -304,7 +300,6 @@ let to_lexeme = function
| Down _ -> "down"
| Else _ -> "else"
| End _ -> "end"
| Entrypoint _ -> "entrypoint"
| Fail _ -> "fail"
| For _ -> "for"
| From _ -> "from"
@ -326,7 +321,6 @@ let to_lexeme = function
| Set _ -> "set"
| Skip _ -> "skip"
| Step _ -> "step"
| Storage _ -> "storage"
| Then _ -> "then"
| To _ -> "to"
| Type _ -> "type"
@ -366,7 +360,6 @@ let keywords = [
(fun reg -> Down reg);
(fun reg -> Else reg);
(fun reg -> End reg);
(fun reg -> Entrypoint reg);
(fun reg -> For reg);
(fun reg -> From reg);
(fun reg -> Function reg);
@ -388,7 +381,6 @@ let keywords = [
(fun reg -> Set reg);
(fun reg -> Skip reg);
(fun reg -> Step reg);
(fun reg -> Storage reg);
(fun reg -> Then reg);
(fun reg -> To reg);
(fun reg -> Type reg);
@ -576,7 +568,6 @@ let is_kwd = function
| Down _
| Else _
| End _
| Entrypoint _
| Fail _
| For _
| From _
@ -598,7 +589,6 @@ let is_kwd = function
| Set _
| Skip _
| Step _
| Storage _
| Then _
| To _
| Type _

View File

@ -53,7 +53,6 @@
%token <Region.t> Down (* "down" *)
%token <Region.t> Else (* "else" *)
%token <Region.t> End (* "end" *)
%token <Region.t> Entrypoint (* "entrypoint" *)
%token <Region.t> Fail (* "fail" *)
%token <Region.t> For (* "for" *)
%token <Region.t> Function (* "function" *)
@ -75,7 +74,6 @@
%token <Region.t> Set (* "set" *)
%token <Region.t> Skip (* "skip" *)
%token <Region.t> Step (* "step" *)
%token <Region.t> Storage (* "storage" *)
%token <Region.t> Then (* "then" *)
%token <Region.t> To (* "to" *)
%token <Region.t> Type (* "type" *)

View File

@ -234,7 +234,6 @@ field_decl:
lambda_decl:
fun_decl { FunDecl $1 }
| proc_decl { ProcDecl $1 }
| entry_decl { EntryDecl $1 }
fun_decl:
Function fun_name parameters COLON type_expr Is
@ -260,33 +259,6 @@ fun_decl:
terminator = $11}
in {region; value}}
entry_decl:
Entrypoint fun_name entry_params COLON type_expr Is
seq(local_decl)
block
With expr option(SEMI) {
let stop =
match $11 with
Some region -> region
| None -> expr_to_region $10 in
let region = cover $1 stop
and value = {
kwd_entrypoint = $1;
name = $2;
param = $3;
colon = $4;
ret_type = $5;
kwd_is = $6;
local_decls = $7;
block = $8;
kwd_with = $9;
return = $10;
terminator = $11}
in {region; value}}
entry_params:
par(nsepseq(entry_param_decl,SEMI)) { $1 }
proc_decl:
Procedure fun_name parameters Is
seq(local_decl)
@ -331,22 +303,6 @@ param_decl:
param_type = $4}
in ParamConst {region; value}}
entry_param_decl:
param_decl {
match $1 with
ParamConst const -> EntryConst const
| ParamVar var -> EntryVar var
}
| Storage var COLON param_type {
let stop = type_expr_to_region $4 in
let region = cover $1 stop
and value = {
kwd_storage = $1;
var = $2;
colon = $3;
storage_type = $4}
in EntryStore {region; value}}
param_type:
cartesian { TProd $1 }

View File

@ -144,7 +144,6 @@ and print_type_tuple {value; _} =
and print_lambda_decl = function
FunDecl fun_decl -> print_fun_decl fun_decl
| ProcDecl proc_decl -> print_proc_decl proc_decl
| EntryDecl entry_decl -> print_entry_decl entry_decl
and print_fun_decl {value; _} =
let {kwd_function; name; param; colon;
@ -173,40 +172,6 @@ and print_proc_decl {value; _} =
print_block block;
print_terminator terminator
and print_entry_decl {value; _} =
let {kwd_entrypoint; name; param; colon;
ret_type; kwd_is; local_decls;
block; kwd_with; return; terminator} = value in
print_token kwd_entrypoint "entrypoint";
print_var name;
print_entry_params param;
print_token colon ":";
print_type_expr ret_type;
print_token kwd_is "is";
print_local_decls local_decls;
print_block block;
print_token kwd_with "with";
print_expr return;
print_terminator terminator
and print_entry_params {value; _} =
let {lpar; inside; rpar} = value in
print_token lpar "(";
print_nsepseq ";" print_entry_param_decl inside;
print_token rpar ")"
and print_entry_param_decl = function
EntryConst param_const -> print_param_const param_const
| EntryVar param_var -> print_param_var param_var
| EntryStore param_store -> print_storage param_store
and print_storage {value; _} =
let {kwd_storage; var; colon; storage_type} = value in
print_token kwd_storage "storage";
print_var var;
print_token colon ":";
print_type_expr storage_type
and print_parameters {value; _} =
let {lpar; inside; rpar} = value in
print_token lpar "(";

View File

@ -138,21 +138,12 @@ and field_decl = parser
and lambda_decl = parser
[< _=fun_decl >] -> ()
| [< _=proc_decl >] -> ()
| [< _=entry_decl >] -> ()
and fun_decl = parser
[< 'Function _; 'Ident _; _=parameters; 'COLON _;
_=type_expr; 'Is _; _ = seq local_decl; _=block;
'With _; _=expr >] -> ()
and entry_decl = parser
[< 'Entrypoint _; 'Ident _; _=entry_params;
'COLON _; _ = type_expr; 'Is _; _ = seq local_decl;
_=block; 'With _; _=expr >] -> ()
and entry_params = parser
[< p = par (nsepseq entry_param_decl semi) >] -> p
and proc_decl = parser
[< 'Procedure _; 'Ident _; _parameters; 'Is _;
_ = seq local_decl; _=block >] -> ()
@ -164,10 +155,6 @@ and param_decl = parser
[< 'Var _; 'Ident _; 'COLON _; _=param_type >] -> ()
| [< 'Const _; 'Ident _; 'COLON _; _=param_type >] -> ()
and entry_param_decl = parser
[< _ = param_decl >] -> ()
| [< 'Storage _; 'Ident _; 'COLON _; _=param_type >] -> ()
and param_type = parser [< c = cartesian >] -> c
and block = parser

View File

@ -1,74 +1,55 @@
const cmp_check : bool = 0 < 1
(*
const cmp_check : bool = ("1970-01-01T00:00:00Z" : timestamp) < ("1970-01-01T00:01:00Z" : timestamp))
*)
const x : int = (3 : int)
type store is
record [
goal : nat;
goal : mutez;
deadline : timestamp;
backers : map (address, nat);
funded : bool;
]
entrypoint contribute (storage store : store;
const sender : address;
const amount : mutez)
: store * list (operation) is
var operations : list (operation) := nil
// const s : list (int) = list [1; 2; 3]
// const t : set (int) = set []
function back (var store : store) : list (operation) * store is
var operations : list (operation) := list []
begin
if now (Unit) > store.deadline then
if now > store.deadline then
fail "Deadline passed";
else
case store.backers[sender] of [
None -> store.backers[sender] := Some (amount)
// None -> patch store.backers with map sender -> amount end
None -> store.backers[sender] := amount
// or: None -> patch store.backers with map sender -> amount end
| _ -> skip
]
end with (store, operations)
end with (operations, store)
entrypoint withdraw (storage store : store; const sender : address)
: store * list (operation) is
var operations : list (operation) := list end
begin
// if set ["a"; "b"] contains x then skip else skip;
if sender = owner then
if now (Unit) >= store.deadline then
if balance >= store.goal then {
store.funded := True;
// patch store with record funded = True end;
operations := list [Transfer (owner, balance)];
};
else fail "Below target"
else block { fail "Too soon"; }
else skip
end with (store, operations)
entrypoint claim (storage store : store; const sender : address)
: store * list (operation) is
var operations : list (operation) := list []
var amount : mutez := 0
function claim (var store : store) : list (operation) * store is
var operations : list (operation) := nil
begin
if now <= store.deadline then
fail "Too soon"
fail "Too soon."
else
case store.backers[sender] of
None ->
fail "Not a backer"
fail "Not a backer."
| Some (amount) ->
if balance >= store.goal or store.funded then
fail "Cannot refund"
fail "Goal reached: no refund."
else
begin
operations := list [Transfer (sender, amount)];
operations := list [transaction (unit, sender, amount)];
remove sender from map store.backers
end
end
end with (store, operations)
end with (operations, store)
function withdraw (var store : store) : list (operation) * store is
var operations : list (operation) := list end
begin
if sender = owner then
if now >= store.deadline then
if balance >= store.goal then {
store.funded := True;
// or: patch store with record funded = True end;
operations := list [Transfer (owner, balance)];
};
else fail "Below target."
else fail "Too soon.";
else skip
end with (operations, store)

View File

@ -28,11 +28,11 @@
source regions, so useful error messages can be printed, therefore
they are part of the signature [TOKEN] that parameterises the
functor generated here. For instance, if, in a future release of
LIGO, new tokens may be added, and the recognition of their lexemes
may entail new errors, the signature [TOKEN] will have to be
augmented and the lexer specification changed. However, in
practice, it is more likely that instructions or types are added,
instead of new kinds of tokens.
LIGO, new tokens are added, and the recognition of their lexemes
entails new errors, the signature [TOKEN] will have to be augmented
and this lexer specification changed. However, in practice, it is
more likely that instructions or types will be added, instead of
new kinds of tokens.
*)
module Region = Simple_utils.Region

View File

@ -461,7 +461,6 @@ let nl = ['\n' '\r'] | "\r\n"
let blank = ' ' | '\t'
let digit = ['0'-'9']
let natural = digit | digit (digit | '_')* digit
let integer = '-'? natural
let small = ['a'-'z']
let capital = ['A'-'Z']
let letter = small | capital
@ -503,7 +502,7 @@ and scan state = parse
| bytes { (mk_bytes seq) state lexbuf |> enqueue }
| natural 'n' { mk_nat state lexbuf |> enqueue }
| natural "mtz" { mk_mtz state lexbuf |> enqueue }
| integer { mk_int state lexbuf |> enqueue }
| natural { mk_int state lexbuf |> enqueue }
| symbol { mk_sym state lexbuf |> enqueue }
| eof { mk_eof state lexbuf |> enqueue }
@ -546,7 +545,7 @@ and scan state = parse
processed).
*)
| '#' blank* ("line" blank+)? (integer as line) blank+
| '#' blank* ("line" blank+)? (natural as line) blank+
'"' (string as file) '"' {
let _, _, state = sync state lexbuf in
let flags, state = scan_flags state [] lexbuf in
@ -562,7 +561,7 @@ and scan state = parse
Some special errors are recognised in the semantic actions of the
following regular expressions. The first error is a minus sign
separated from the integer it modifies by some markup (space or
separated from the integer it applies by some markup (space or
tabs). The second is a minus sign immediately followed by
anything else than a natural number (matched above) or markup and
a number (previous error). The third is the strange occurrence of
@ -581,7 +580,7 @@ and scan state = parse
fail region Orphan_minus
| _ -> fail region Unterminated_integer }
| '-' "0x" byte_seq?
| "-0x" byte_seq?
{ let region, _, _ = sync state lexbuf
in fail region Negative_byte_sequence }
@ -593,7 +592,7 @@ and scan state = parse
and scan_flags state acc = parse
blank+ { let _, _, state = sync state lexbuf
in scan_flags state acc lexbuf }
| integer as code { let _, _, state = sync state lexbuf in
| natural as code { let _, _, state = sync state lexbuf in
let acc = int_of_string code :: acc
in scan_flags state acc lexbuf }
| nl { List.rev acc, push_newline state lexbuf }
@ -699,7 +698,7 @@ and scan_utf8 thread state = parse
report special error patterns), we need to keep a hidden reference
to a queue of recognised lexical units (that is, tokens and markup)
that acts as a mutable state between the calls to
[read_token]. When [read_token] is called, that queue is consulted
[read_token]. When [read_token] is called, that queue is examined
first and, if it contains at least one token, that token is
returned; otherwise, the lexing buffer is scanned for at least one
more new token. That is the general principle: we put a high-level
@ -794,19 +793,18 @@ let open_token_stream file_path_opt =
Some ([], next) ->
let pos = (Token.to_region token)#stop in
let region = Region.make ~start:pos ~stop:pos in
if is_bytes token && is_int next then
if is_int next then
fail region Odd_lengthed_bytes
else
if is_ident next || is_string next
|| is_bytes next || is_int next then
if is_ident next || is_string next || is_bytes next then
fail region Missing_break
| _ -> ()
else
if Token.is_ident token || Token.is_string token then
if is_ident token || is_string token then
match next_token buffer with
Some ([], next) ->
if Token.is_ident next || Token.is_string next
|| Token.is_bytes next || Token.is_int next
if is_ident next || is_string next
|| is_bytes next || is_int next
then
let pos = (Token.to_region token)#stop in
let region = Region.make ~start:pos ~stop:pos

View File

@ -100,28 +100,6 @@ module Errors = struct
] in
error ~data title message
let unsupported_string_catenation expr =
let title () = "string expressions" in
let message () =
Format.asprintf "string concatenation is not supported yet" in
let expr_loc = Raw.expr_to_region expr in
let data = [
("expr_loc",
fun () -> Format.asprintf "%a" Location.pp_lift @@ expr_loc)
] in
error ~data title message
let unsupported_set_expr expr =
let title () = "set expressions" in
let message () =
Format.asprintf "the set type is not supported yet" in
let expr_loc = Raw.expr_to_region expr in
let data = [
("expr_loc",
fun () -> Format.asprintf "%a" Location.pp_lift @@ expr_loc)
] in
error ~data title message
let unsupported_proc_calls call =
let title () = "procedure calls" in
let message () =