mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-16 03:38:47 +00:00
Better error reporting for infixes
This commit is contained in:
parent
a12f9337e9
commit
faca5c6e0e
3 changed files with 28 additions and 14 deletions
|
|
@ -110,7 +110,7 @@ class options args =
|
||||||
end
|
end
|
||||||
|
|
||||||
let main =
|
let main =
|
||||||
(* try *)
|
try
|
||||||
let cmd = new options Sys.argv in
|
let cmd = new options Sys.argv in
|
||||||
match (try parse cmd with Language.Semantic_error msg -> `Fail msg) with
|
match (try parse cmd with Language.Semantic_error msg -> `Fail msg) with
|
||||||
| `Ok prog ->
|
| `Ok prog ->
|
||||||
|
|
@ -119,9 +119,7 @@ let main =
|
||||||
| `Default | `Compile ->
|
| `Default | `Compile ->
|
||||||
ignore @@ X86.build cmd prog
|
ignore @@ X86.build cmd prog
|
||||||
| _ ->
|
| _ ->
|
||||||
(* Printf.printf "Program:\n%s\n" (GT.show(Language.Expr.t) prog);*)
|
let rec read acc =
|
||||||
(*Format.printf "Program\n%s\n%!" (HTML.toHTML ((GT.html(Language.Expr.t)) prog));*)
|
|
||||||
let rec read acc =
|
|
||||||
try
|
try
|
||||||
let r = read_int () in
|
let r = read_int () in
|
||||||
Printf.printf "> ";
|
Printf.printf "> ";
|
||||||
|
|
@ -137,5 +135,5 @@ let main =
|
||||||
List.iter (fun i -> Printf.printf "%d\n" i) output
|
List.iter (fun i -> Printf.printf "%d\n" i) output
|
||||||
)
|
)
|
||||||
| `Fail er -> Printf.eprintf "Error: %s\n" er
|
| `Fail er -> Printf.eprintf "Error: %s\n" er
|
||||||
(*with Language.Semantic_error msg -> Printf.printf "Error: %s\n" msg *)
|
with Language.Semantic_error msg -> Printf.printf "Error: %s\n" msg
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,18 +8,34 @@ open GT
|
||||||
(* Opening a library for combinator-based syntax analysis *)
|
(* Opening a library for combinator-based syntax analysis *)
|
||||||
open Ostap
|
open Ostap
|
||||||
open Combinators
|
open Combinators
|
||||||
|
|
||||||
|
module Subst =
|
||||||
|
struct
|
||||||
|
|
||||||
|
module H = Hashtbl.Make (struct type t = string let hash = Hashtbl.hash let equal = (=) end)
|
||||||
|
|
||||||
|
let tab = (H.create 1024 : string H.t)
|
||||||
|
|
||||||
|
let attach infix op = H.add tab infix op
|
||||||
|
let subst id = match H.find_opt tab id with None -> id | Some op -> op
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
let infix_name infix =
|
let infix_name infix =
|
||||||
let b = Buffer.create 64 in
|
let b = Buffer.create 64 in
|
||||||
Buffer.add_string b "i__Infix_";
|
Buffer.add_string b "i__Infix_";
|
||||||
Seq.iter (fun c -> Buffer.add_string b (string_of_int @@ Char.code c)) @@ String.to_seq infix;
|
Seq.iter (fun c -> Buffer.add_string b (string_of_int @@ Char.code c)) @@ String.to_seq infix;
|
||||||
Buffer.contents b
|
let s = Buffer.contents b in
|
||||||
|
Subst.attach s ("operator " ^ infix);
|
||||||
|
s
|
||||||
|
|
||||||
let sys_infix_name infix =
|
let sys_infix_name infix =
|
||||||
let b = Buffer.create 64 in
|
let b = Buffer.create 64 in
|
||||||
Buffer.add_string b "s__Infix_";
|
Buffer.add_string b "s__Infix_";
|
||||||
Seq.iter (fun c -> Buffer.add_string b (string_of_int @@ Char.code c)) @@ String.to_seq infix;
|
Seq.iter (fun c -> Buffer.add_string b (string_of_int @@ Char.code c)) @@ String.to_seq infix;
|
||||||
Buffer.contents b
|
let s = Buffer.contents b in
|
||||||
|
Subst.attach s ("operator " ^ infix);
|
||||||
|
s
|
||||||
|
|
||||||
exception Semantic_error of string
|
exception Semantic_error of string
|
||||||
|
|
||||||
|
|
@ -180,10 +196,10 @@ module State =
|
||||||
|
|
||||||
(* Undefined state *)
|
(* Undefined state *)
|
||||||
let undefined x =
|
let undefined x =
|
||||||
report_error ~loc:(Loc.get x) (Printf.sprintf "undefined name \"%s\"" x)
|
report_error ~loc:(Loc.get x) (Printf.sprintf "undefined name \"%s\"" (Subst.subst x))
|
||||||
|
|
||||||
(* Create a state from bindings list *)
|
(* Create a state from bindings list *)
|
||||||
let from_list l = fun x -> try List.assoc x l with Not_found -> report_error ~loc:(Loc.get x) (Printf.sprintf "undefined name \"%s\"" x)
|
let from_list l = fun x -> try List.assoc x l with Not_found -> report_error ~loc:(Loc.get x) (Printf.sprintf "undefined name \"%s\"" (Subst.subst x))
|
||||||
|
|
||||||
(* Bind a variable to a value in a state *)
|
(* Bind a variable to a value in a state *)
|
||||||
let bind x v s = fun y -> if x = y then v else s y
|
let bind x v s = fun y -> if x = y then v else s y
|
||||||
|
|
@ -206,12 +222,12 @@ module State =
|
||||||
| G (scope, s) ->
|
| G (scope, s) ->
|
||||||
if is_var x scope
|
if is_var x scope
|
||||||
then G (scope, bind x v s)
|
then G (scope, bind x v s)
|
||||||
else report_error ~loc:(Loc.get x) (Printf.sprintf "name \"%s\" is undefined or does not designate a variable" x)
|
else report_error ~loc:(Loc.get x) (Printf.sprintf "name \"%s\" is undefined or does not designate a variable" (Subst.subst x))
|
||||||
| L (scope, s, enclosing) ->
|
| L (scope, s, enclosing) ->
|
||||||
if in_scope x scope
|
if in_scope x scope
|
||||||
then if is_var x scope
|
then if is_var x scope
|
||||||
then L (scope, bind x v s, enclosing)
|
then L (scope, bind x v s, enclosing)
|
||||||
else report_error ~loc:(Loc.get x) (Printf.sprintf "name \"%s\" does not designate a variable" x)
|
else report_error ~loc:(Loc.get x) (Printf.sprintf "name \"%s\" does not designate a variable" (Subst.subst x))
|
||||||
else L (scope, s, inner enclosing)
|
else L (scope, s, inner enclosing)
|
||||||
in
|
in
|
||||||
inner s
|
inner s
|
||||||
|
|
@ -443,7 +459,7 @@ module Expr =
|
||||||
([], body, [])
|
([], body, [])
|
||||||
(List.rev @@
|
(List.rev @@
|
||||||
List.map (function
|
List.map (function
|
||||||
| (name, (`Extern, _)) -> report_error (Printf.sprintf "external names (\"%s\") not supported in evaluation" name)
|
| (name, (`Extern, _)) -> report_error (Printf.sprintf "external names (\"%s\") not supported in evaluation" (Subst.subst name))
|
||||||
| x -> x
|
| x -> x
|
||||||
)
|
)
|
||||||
defs)
|
defs)
|
||||||
|
|
|
||||||
|
|
@ -247,7 +247,7 @@ let scope_label i s = label s ^ "_" ^ string_of_int i
|
||||||
|
|
||||||
let check_name_and_add names name mut =
|
let check_name_and_add names name mut =
|
||||||
if List.exists (fun (n, _) -> n = name) names
|
if List.exists (fun (n, _) -> n = name) names
|
||||||
then report_error ~loc:(Loc.get name) (Printf.sprintf "name \"%s\" is already defined in the scope" name)
|
then report_error ~loc:(Loc.get name) (Printf.sprintf "name \"%s\" is already defined in the scope" (Subst.subst name))
|
||||||
else (name, mut) :: names
|
else (name, mut) :: names
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
|
@ -543,7 +543,7 @@ object (self : 'self)
|
||||||
match m with
|
match m with
|
||||||
| `Local -> ()
|
| `Local -> ()
|
||||||
| _ ->
|
| _ ->
|
||||||
report_error (Printf.sprintf "external/public definitions (\"%s\") not allowed in local scopes" name)
|
report_error (Printf.sprintf "external/public definitions (\"%s\") not allowed in local scopes" (Subst.subst name))
|
||||||
|
|
||||||
method add_name (name : string) (m : [`Local | `Extern | `Public | `PublicExtern]) (mut : bool) = {<
|
method add_name (name : string) (m : [`Local | `Extern | `Public | `PublicExtern]) (mut : bool) = {<
|
||||||
decls = (name, m, false) :: decls;
|
decls = (name, m, false) :: decls;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue