Skip to content

Commit

Permalink
implement source type to hold file content in memory (fixes #26)
Browse files Browse the repository at this point in the history
  • Loading branch information
eWert-Online committed Mar 24, 2024
1 parent 8ef749c commit f220e38
Show file tree
Hide file tree
Showing 19 changed files with 194 additions and 135 deletions.
7 changes: 3 additions & 4 deletions benchmark/benchmark.ml
Original file line number Diff line number Diff line change
Expand Up @@ -165,22 +165,21 @@ end = struct
;;

let benchmark filename action =
let src = In_channel.with_open_bin filename In_channel.input_all in
let src = Pinc.Source.of_file filename in
let benchmarkFn =
match action with
| Parse ->
fun _ ->
let _ = Sys.opaque_identity (Pinc.Parser.parse ~filename src) in
let _ = Sys.opaque_identity (Pinc.Parser.parse src) in
()
| Interp root ->
let ast = Pinc.Parser.parse ~filename src in
fun _ ->
let _ =
Sys.opaque_identity
(Pinc.Interpreter.eval
~tag_data_provider:Pinc.Interpreter.noop_data_provider
~root
ast)
[ src ])
in
()
in
Expand Down
18 changes: 1 addition & 17 deletions bin/print.ml
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,7 @@ let get_files_with_ext ~ext dir =
;;

let get_declarations_from ~directory () =
directory
|> get_files_with_ext ~ext:".pi"
|> List.fold_left
(fun acc filename ->
let decls =
In_channel.with_open_bin filename In_channel.input_all
|> Parser.parse ~filename
in
let f key _ _ =
Pinc_Diagnostics.error
(Pinc_Diagnostics.Location.make
~s:(Pinc_Diagnostics.Location.Position.make ~filename ~line:0 ~column:0)
())
("Found multiple declarations with identifier " ^ key)
in
StringMap.union f acc decls)
StringMap.empty
directory |> get_files_with_ext ~ext:".pi" |> List.map Source.of_file
;;

let main =
Expand Down
13 changes: 2 additions & 11 deletions bin/print_debug.ml
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
open Pinc

let get_source filename =
let file_contents chan = really_input_string chan (in_channel_length chan) in
let chan = open_in filename in
let src = chan |> file_contents in
close_in chan;
src
;;

let main =
let filename = Sys.argv.(1) in
let root = Sys.argv.(2) in
let src = filename |> get_source in
let src = filename |> Source.of_file in
let start_time = Unix.gettimeofday () in
let ast = src |> Parser.parse ~filename in
let end_time_parser = Unix.gettimeofday () in
let result =
ast |> Interpreter.eval ~tag_data_provider:Interpreter.noop_data_provider ~root
[ src ] |> Interpreter.eval ~tag_data_provider:Interpreter.noop_data_provider ~root
in
let end_time = Unix.gettimeofday () in
Printf.printf "Lexer & Parser: %fms\n" ((end_time_parser -. start_time) *. 1000.);
Expand Down
1 change: 1 addition & 0 deletions lib/Pinc.ml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
module Source = Pinc_Core.Source
module Ast = Pinc_Frontend.Ast
module Parser = Pinc_Frontend.Parser

Expand Down
43 changes: 36 additions & 7 deletions lib/pinc_backend/Interpreter.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module Types = Types
module Ast = Pinc_Frontend.Ast
module Parser = Pinc_Frontend.Parser
module Location = Pinc_Diagnostics.Location
module Source = Pinc_Core.Source

exception Loop_Break of state
exception Loop_Continue of state
Expand Down Expand Up @@ -1303,7 +1304,24 @@ and eval_template ~state template =

let noop_data_provider ~tag:_ ~attributes:_ ~key:_ = None

let eval_meta declarations =
let declarations_of_sources sources =
ListLabels.fold_left sources ~init:StringMap.empty ~f:(fun acc source ->
let decls = Parser.parse source in
let f key _ _ =
Pinc_Diagnostics.error
(Pinc_Diagnostics.Location.make
~s:(Pinc_Diagnostics.Location.Position.make ~source ~line:0 ~column:0)
())
(Printf.sprintf
"Found multiple declarations with identifier `%s`.\n\
Every declaration has to have a unique name in pinc."
key)
in
StringMap.union f acc decls)
;;

let eval_meta sources =
let declarations = declarations_of_sources sources in
let state =
State.make
~mode:`Portal_Collection
Expand All @@ -1330,25 +1348,36 @@ let eval_meta declarations =
let get_stdlib () =
let open Pinc_Includes in
Includes.file_list
|> List.map (fun filename ->
filename |> Includes.read |> Option.get |> Source.of_string ~filename)
|> List.fold_left
(fun acc filename ->
let decls = filename |> Includes.read |> Option.get |> Parser.parse ~filename in
(fun acc source ->
let decls = source |> Parser.parse in
let f key _ _ =
Pinc_Diagnostics.error
(Pinc_Diagnostics.Location.make
~s:(Pinc_Diagnostics.Location.Position.make ~filename ~line:0 ~column:0)
~s:(Pinc_Diagnostics.Location.Position.make ~source ~line:0 ~column:0)
())
("Found multiple declarations with identifier " ^ key)
in
StringMap.union f acc decls)
StringMap.empty
;;

let eval ~tag_data_provider ~root declarations =
let eval ~tag_data_provider ~root sources =
Hashtbl.reset Tag.Tag_Portal.portals;

let base_lib = get_stdlib () in
let declarations = StringMap.union (fun _key _x y -> Some y) base_lib declarations in
let declarations =
StringMap.union
(fun _key _x y -> Some y)
(get_stdlib ())
(declarations_of_sources sources)
in

(match declarations |> StringMap.find_opt root with
| Some { declaration_type = Declaration_Library _ | Declaration_Store _; _ } ->
raise_notrace (Invalid_argument (root ^ " can not be evaluated"))
| _ -> ());

let state =
State.make
Expand Down
9 changes: 7 additions & 2 deletions lib/pinc_backend/Interpreter.mli
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ open Types
val noop_data_provider : Type_Tag.data_provider

val eval_meta :
Ast.t ->
Pinc_Core.Source.t list ->
[> `Component of value StringMap.t
| `Library of value StringMap.t
| `Page of value StringMap.t
| `Store of value StringMap.t
]
StringMap.t

(** [eval ~tag_data_provider ~root sources] evaluates definition {!root} found in {!sources}, getting its data from the {!tag_data_provider}.
@raise Invalid_argument if the given root can't be evaluated (store, library). *)
val eval :
tag_data_provider:Types.Type_Tag.data_provider -> root:StringMap.key -> Ast.t -> string
tag_data_provider:Types.Type_Tag.data_provider ->
root:string ->
Pinc_Core.Source.t list ->
string
1 change: 1 addition & 0 deletions lib/pinc_core/Pinc_Core.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module Source = Pinc_Source
28 changes: 28 additions & 0 deletions lib/pinc_core/Pinc_Source.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
type t =
| Empty
| File of string
| String of string option * string

let empty = Empty
let of_string ?filename content = String (filename, content)
let of_file path = File path

let name = function
| Empty -> None
| File name -> Some name
| String (name, _) -> name
;;

let length = function
| Empty -> 0
| File filename -> (
try In_channel.(with_open_bin filename length) |> Int64.to_int
with _ -> invalid_arg "file size is larger than an OCaml 63-bit integer")
| String (_name, content) -> String.length content
;;

let content = function
| Empty -> ""
| File filename -> In_channel.(with_open_bin filename input_all)
| String (_name, content) -> content
;;
8 changes: 8 additions & 0 deletions lib/pinc_core/Pinc_Source.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
type t

val empty : t
val of_string : ?filename:string -> string -> t
val of_file : string -> t
val name : t -> string option
val length : t -> int
val content : t -> string
5 changes: 5 additions & 0 deletions lib/pinc_core/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(library
(name Pinc_Core)
(public_name pinc-lang.core)
(instrumentation
(backend bisect_ppx)))
4 changes: 2 additions & 2 deletions lib/pinc_diagnostics/Pinc_Location.ml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ let make ?e ~s () =

let none =
{
loc_start = Position.make ~filename:"" ~line:0 ~column:0;
loc_end = Position.make ~filename:"" ~line:0 ~column:0;
loc_start = Position.make ~source:Pinc_Core.Source.empty ~line:0 ~column:0;
loc_end = Position.make ~source:Pinc_Core.Source.empty ~line:0 ~column:0;
}
;;
4 changes: 2 additions & 2 deletions lib/pinc_diagnostics/Pinc_Position.ml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
type t = {
filename : string;
source : Pinc_Core.Source.t;
line : int;
beginning_of_line : int;
column : int;
}

let make ~filename ~line ~column = { filename; line; beginning_of_line = 0; column }
let make ~source ~line ~column = { source; line; beginning_of_line = 0; column }
4 changes: 2 additions & 2 deletions lib/pinc_diagnostics/Pinc_Position.mli
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
type t = {
filename : string;
source : Pinc_Core.Source.t;
line : int;
beginning_of_line : int;
column : int;
}

val make : filename:string -> line:int -> column:int -> t
val make : source:Pinc_Core.Source.t -> line:int -> column:int -> t
Loading

0 comments on commit f220e38

Please sign in to comment.