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