Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lib/ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ module ReadSpreadsheet = struct
;;
end

module Import = struct
type t =
{ var : Variable.T.t
; from : Variable.T.t
}
[@@deriving sexp]

let to_string node = Printf.sprintf "Import %s from %s" node.var node.from
end

module Export = struct
type t =
| File of string
Expand All @@ -71,6 +81,7 @@ module Node = struct
| ReadConstant of ReadConstant.t
| ReadVariable of ReadVariable.t
| ReadSpreadsheet of ReadSpreadsheet.t
| Import of Import.t
| Export of Export.t
[@@deriving sexp]

Expand All @@ -79,6 +90,7 @@ module Node = struct
| ReadConstant n -> ReadConstant.to_string n
| ReadVariable n -> ReadVariable.to_string n
| ReadSpreadsheet n -> ReadSpreadsheet.to_string n
| Import n -> Import.to_string n
| Export n -> Export.to_string n
;;
end
12 changes: 12 additions & 0 deletions lib/ast.mli
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ module ReadSpreadsheet : sig
val to_string : t -> string
end

module Import : sig
type t =
{ var : Variable.T.t
; from : Variable.T.t
}

val t_of_sexp : Sexplib0.Sexp.t -> t
val sexp_of_t : t -> Sexplib0.Sexp.t
val to_string : t -> string
end

module Export : sig
type t =
| File of string
Expand All @@ -47,6 +58,7 @@ module Node : sig
| ReadConstant of ReadConstant.t
| ReadVariable of ReadVariable.t
| ReadSpreadsheet of ReadSpreadsheet.t
| Import of Import.t
| Export of Export.t

val t_of_sexp : Sexplib0.Sexp.t -> t
Expand Down
3 changes: 3 additions & 0 deletions lib/import.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module T = struct
let to_string (var, from) = Printf.sprintf "import { %s } from \"%s\";" var from
end
3 changes: 3 additions & 0 deletions lib/import.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module T : sig
val to_string : string * Variable.T.t -> string
end
13 changes: 13 additions & 0 deletions lib/interpreter.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module T = struct
{ variable_store : Literal.T.v Store.T.t
; spreadsheet_store : Spreadsheet.t Store.T.t
; interface_set : Variable.T.t Store.T.t
; import_store : Variable.T.t Store.T.t
}

let interpret_read_constant state (node : Ast.ReadConstant.t) =
Expand Down Expand Up @@ -39,7 +40,15 @@ module T = struct
| Csv p -> interpret_csv_spreadsheet state variable interface p
;;

let interpret_import state (node : Ast.Import.t) =
let target, from = node.var, node.from in
if not (Variable.T.is_valid target)
then failwith ("invalid import value name " ^ target);
Store.T.set_key state.import_store target from
;;

let interpret_export state (node : Ast.Export.t) =
let import_contents = Store.T.to_string state.import_store Import.T.to_string in
let var_contents = Store.T.to_string state.variable_store Literal.T.to_string in
let spreadsheet_contents =
Store.T.to_string state.spreadsheet_store Spreadsheet.Writer.to_string
Expand All @@ -48,8 +57,10 @@ module T = struct
Printf.sprintf
{|
%s
%s
%s
|}
import_contents
var_contents
spreadsheet_contents
in
Expand All @@ -69,6 +80,7 @@ module T = struct
| Ast.Node.ReadConstant n -> interpret_read_constant state n
| Ast.Node.ReadVariable n -> interpret_read_variable state n
| Ast.Node.ReadSpreadsheet n -> interpret_read_spreadsheet state n
| Ast.Node.Import n -> interpret_import state n
| Ast.Node.Export n ->
interpret_export state n;
reset_state state
Expand All @@ -78,6 +90,7 @@ module T = struct
{ variable_store = Store.T.create ()
; spreadsheet_store = Store.T.create ()
; interface_set = Store.T.create ()
; import_store = Store.T.create ()
}
;;

Expand Down
1 change: 1 addition & 0 deletions lib/interpreter.mli
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module T : sig
{ variable_store : Literal.T.v Store.T.t
; spreadsheet_store : Spreadsheet.t Store.T.t
; interface_set : Variable.T.t Store.T.t
; import_store : Variable.T.t Store.T.t
}

val interpret_node : state -> Ast.Node.t -> unit
Expand Down
1 change: 1 addition & 0 deletions test/expect_tests/cases/basic_program_test.sexp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
(
(Import ((var SomeEnum) (from some-file.ts)))
(ReadConstant ((var "thing") (value (String "ABCDEF"))))
(ReadConstant ((var "thing2") (value (Integer 123))))
(ReadVariable ((var "thing3") (value (Float 3.14))))
Expand Down
5 changes: 5 additions & 0 deletions test/expect_tests/cases/fail_dupe_import.sexp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(
(Import ((var SomeEnum) (from some-file.ts)))
(Import ((var SomeEnum) (from some-file-2.ts)))
(Export Stdout)
)
3 changes: 3 additions & 0 deletions test/expect_tests/cases/long_program_test.sexp
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
(
(Import ((var SomeEnum) (from some-file.ts)))
(Import ((var SomeOtherEnum) (from some-other-file.ts)))
(Import ((var SomeOtherEnum2) (from some-other-file.ts)))
(ReadConstant ((var "thing") (value (String "ABCDEF"))))
(ReadConstant ((var "thing2") (value (Integer 123))))
(ReadSpreadsheet ((var "spreadsheet_123") (interface "SomeType") (path (Csv "./data/sample_spreadsheet.csv"))))
Expand Down
2 changes: 2 additions & 0 deletions test/expect_tests/cases/medium_program_test.sexp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
(
(Import ((var SomeEnum) (from some-file.ts)))
(Import ((var SomeOtherEnum) (from some-other-file.ts)))
(ReadConstant ((var "dataset_name") (value (String "PEOPLE_NAMES"))))
(ReadSpreadsheet ((var "people_names") (interface "Person") (path (Csv "./data/sample_spreadsheet_medium.csv"))))
(Export Stdout)
Expand Down
13 changes: 13 additions & 0 deletions test/expect_tests/end_to_end_program_tests.ml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ let%expect_test "passes basic end to end test" =
Entry.entry_point "basic_program_test.sexp";
[%expect
{|
import { SomeEnum } from "some-file.ts";
export const thing2: number = 123;
export const thing5: string = "a afsdafds afsdsa";
export const thing: string = "ABCDEF";
Expand All @@ -31,6 +32,8 @@ let%expect_test "passes long end to end test" =
Entry.entry_point "medium_program_test.sexp";
[%expect
{|
import { SomeEnum } from "some-file.ts";
import { SomeOtherEnum } from "some-other-file.ts";
export const dataset_name: string = "PEOPLE_NAMES";

export interface Person {
Expand Down Expand Up @@ -79,6 +82,9 @@ let%expect_test "passes long end to end test" =
Entry.entry_point "long_program_test.sexp";
[%expect
{|
import { SomeEnum } from "some-file.ts";
import { SomeOtherEnum } from "some-other-file.ts";
import { SomeOtherEnum2 } from "some-other-file.ts";
export const thing2: number = 123;
export const thing: string = "ABCDEF";

Expand Down Expand Up @@ -260,3 +266,10 @@ let%expect_test "fails on duplicate interface name" =
print_endline msg;
[%expect {| variable SomeType already set |}]
;;

let%expect_test "fails on duplicate imported modules" =
try Entry.entry_point "fail_dupe_import.sexp" with
| Failure msg ->
print_endline msg;
[%expect {| variable SomeEnum already set |}]
;;
66 changes: 66 additions & 0 deletions test/expect_tests/import_tests.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
open Conkeldurr

let%expect_test "can import a basic file" =
let program =
{|
((Import ((var abc) (from banana.ts)))
(Export Stdout))
|}
in
program |> Program.T.of_string |> Interpreter.T.interpret;
[%expect
{|
import { abc } from "banana.ts";
|}]
;;

let%expect_test "can import multiple files" =
let program =
{|
(
(Import ((var abc) (from banana/banana)))
(Import ((var def) (from abcdef)))
(Import ((var react) (from react)))
(Export Stdout))
|}
in
program |> Program.T.of_string |> Interpreter.T.interpret;
[%expect
{|
import { abc } from "banana/banana";
import { def } from "abcdef";
import { react } from "react";
|}]
;;

let%expect_test "can import multiple exports from one file" =
let program =
{|
(
(Import ((var abc) (from banana/banana)))
(Import ((var def) (from banana/banana)))
(Export Stdout))
|}
in
program |> Program.T.of_string |> Interpreter.T.interpret;
[%expect
{|
import { abc } from "banana/banana";
import { def } from "banana/banana";
|}]
;;

let%expect_test "fails on importing identical exports" =
let program =
{|
(
(Import ((var abc) (from banana/banana)))
(Import ((var abc) (from abcdef)))
(Export Stdout))
|}
in
try program |> Program.T.of_string |> Interpreter.T.interpret with
| Failure msg ->
print_endline msg;
[%expect {| variable abc already set |}]
;;