diff --git a/lib/DhallishGrammar.treetop b/lib/DhallishGrammar.treetop index f88c58ea7fc3583178bd1d54a74d04f8d30bdfde..aa919ff0101af5ddd5a0496127af5c976f492def 100644 --- a/lib/DhallishGrammar.treetop +++ b/lib/DhallishGrammar.treetop @@ -371,7 +371,8 @@ grammar DhallishGrammar exp:label { def to_node(ctx) exp.to_node(ctx) end } / exp:record_literal { def to_node(ctx) exp.to_node(ctx) end } / exp:record_type_literal { def to_node(ctx) exp.to_node(ctx) end } / - "(" space? exp:expression space? ")" { def to_node(ctx) exp.to_node(ctx) end } + "(" space? exp:expression space? ")" { def to_node(ctx) exp.to_node(ctx) end } / + "???" { def to_node(ctx) Dhallish::Ast::GetContext.new end } end ## End of operator expressions diff --git a/lib/ast.rb b/lib/ast.rb index 744fce87af6cd924dfd7ce21819abef1900125ff..84aead776d1cdc37b9a3b9183199db9dde48b34d 100644 --- a/lib/ast.rb +++ b/lib/ast.rb @@ -690,12 +690,12 @@ module Dhallish class Literal_Node attr_accessor :val attr_accessor :type - + def initialize(val, type) @val = val @type = type end - + def compute_type(ctx) @type end @@ -705,5 +705,16 @@ module Dhallish end end + class GetContext + def initialize() @typectx = nil end + + def compute_type(ctx) + @typectx = ctx + Types::Record.new({}) + end + + def evaluate(ctx) { "#valctx#" => ctx, "#typectx#" => @typectx } end + end + end end diff --git a/lib/dhallish.rb b/lib/dhallish.rb index e35cf093e7d923cf602cb3a07d77c78094a1721b..5af922ba8f85e87b887a4fd61f21f1b25735a7ac 100644 --- a/lib/dhallish.rb +++ b/lib/dhallish.rb @@ -24,6 +24,13 @@ module Dhallish ::Dhallish::fill_context(@context, @typectx) end + def evaluate_file(file, ctx = @context, typectx = @typectx) + file = File.open(file) + res = evaluate(file.read, ctx, typectx) + file.close + res + end + def evaluate(dhallcode, ctx = @context, typectx = @typectx) treetopast = @parser.parse dhallcode if treetopast.nil? @@ -32,11 +39,42 @@ module Dhallish ast = treetopast.to_node nil type = ast.compute_type typectx - #puts type return [ast.evaluate(ctx), type] end + def create_ctx_from_file(file) + file = File.open(file) + res = create_ctx(file.read) + file.close + res + end + + def create_ctx(dhallcode) + val, type = evaluate(dhallcode, @context, @typectx) + if !type.is_a? Types::Record or val["#valctx#"].nil? or val["#typectx#"].nil? + raise DhallError, "Dhallish: create_ctx did not return a context! use `???` as a return expression in dhallish for create_ctx" + end + val + end + + def evaluate_in_ctx_from_file(file, dhallctx) + file = File.open(file) + res = evaluate_in_ctx(file.read, dhallctx) + file.close + res + end + + def evaluate_in_ctx(dhallcode, dhallctx) + if !dhallctx.is_a? Hash or dhallctx["#valctx#"].nil? or dhallctx["#typectx#"].nil? + raise DhallError, "Dhallish: evaluate_in_ctx must be called with a context returned by create_ctx" + end + typectx = dhallctx["#typectx#"] + valctx = dhallctx["#valctx#"] + + val, type = evaluate(dhallcode, valctx, typectx) + val + end end end diff --git a/tests/test_dhallish_ctx.rb b/tests/test_dhallish_ctx.rb new file mode 100644 index 0000000000000000000000000000000000000000..bff3cd5c35d51a33ca145d5749ca6866f43863b6 --- /dev/null +++ b/tests/test_dhallish_ctx.rb @@ -0,0 +1,13 @@ +require_relative '../lib/dhallish.rb' + +dhall = Dhallish::Dhallish.new + +ctx = dhall.create_ctx(" +let x = 41 +let f = \\(n: Natural) -> n + 1 +in ??? +") + +res = dhall.evaluate_in_ctx("f x", ctx) + +puts res