From 38649b40f7b6159ee0f1f148dbd83aeadf305a56 Mon Sep 17 00:00:00 2001
From: Philipp Panzer <philipp.panzer@fau.de>
Date: Tue, 5 Mar 2019 12:05:47 +0100
Subject: [PATCH] changed ast and grammar to new interface; broken commit

---
 bin/dhallish                |   2 +-
 lib/DhallishGrammar.treetop |  10 +-
 lib/ast.rb                  | 176 ++++++++++--------------------------
 lib/dhallish.rb             |   2 +-
 4 files changed, 57 insertions(+), 133 deletions(-)

diff --git a/bin/dhallish b/bin/dhallish
index 04abf38..fba0a1e 100755
--- a/bin/dhallish
+++ b/bin/dhallish
@@ -12,7 +12,7 @@ end
 input = $stdin.read
 
 begin
-	output = dhall.evaluate(input).to_json
+	output = dhall.evaluate(input)[0].to_json
 rescue DhallError => err
 	STDERR.puts err
 	exit! 1
diff --git a/lib/DhallishGrammar.treetop b/lib/DhallishGrammar.treetop
index 059a39b..f88c58e 100644
--- a/lib/DhallishGrammar.treetop
+++ b/lib/DhallishGrammar.treetop
@@ -41,7 +41,7 @@ grammar DhallishGrammar
 
 	## Number Literals
 	rule integer_literal
-		("+" / "-") [0-9]+ { def to_node(ctx) Dhallish::Value.new(text_value.to_i, Dhallish::Types::Integer)  end }
+		("+" / "-") [0-9]+ { def to_node(ctx) Dhallish::Ast::Literal_Node.new(text_value.to_i, Dhallish::Types::Integer)  end }
 	end
 
 	rule exponent
@@ -50,19 +50,19 @@ grammar DhallishGrammar
 	end
 
 	rule double_literal
-		("+" / "-")? [0-9]+ (("." [0-9]+ exponent?) / exponent) { def to_node(ctx) Dhallish::Value.new(text_value.to_f, Dhallish::Types::Double) end }
+		("+" / "-")? [0-9]+ (("." [0-9]+ exponent?) / exponent) { def to_node(ctx) Dhallish::Ast::Literal_Node.new(text_value.to_f, Dhallish::Types::Double) end }
 
 	end
 
 	rule natural_literal
-		[0-9]+ { def to_node(ctx) Dhallish::Value.new(text_value.to_i, Dhallish::Types::Natural) end }
+		[0-9]+ { def to_node(ctx) Dhallish::Ast::Literal_Node.new(text_value.to_i, Dhallish::Types::Natural) end }
 	end
 
 	## Bools
 	rule bool_literal
-		"True" { def to_node(ctx) Dhallish::Value.new(true, Dhallish::Types::Bool) end }
+		"True" { def to_node(ctx) Dhallish::Ast::Literal_Node.new(true, Dhallish::Types::Bool) end }
 		/
-		"False" { def to_node(ctx) Dhallish::Value.new(false, Dhallish::Types::Bool) end }
+		"False" { def to_node(ctx) Dhallish::Ast::Literal_Node.new(false, Dhallish::Types::Bool) end }
 	end
 
 	## Lists
diff --git a/lib/ast.rb b/lib/ast.rb
index 38a54b0..744fce8 100644
--- a/lib/ast.rb
+++ b/lib/ast.rb
@@ -31,12 +31,7 @@ module Dhallish
 			def evaluate(ctx)
 				lhs = @lhs.evaluate ctx
 				rhs = @rhs.evaluate ctx
-
-				assert("`#{@op}` takes two args of same type") { lhs.type == rhs.type }
-				assert("`#{@op}` args type missmatch #{lhs.type}, expected: #{@types.join ", "}") { @types.include? lhs.type }
-
-				res = @block.call lhs.val, rhs.val
-				Value.new res, lhs.type
+				@block.call lhs, rhs
 			end
 		end
 
@@ -71,16 +66,7 @@ module Dhallish
 			def evaluate(ctx)
 				lhs = @lhs.evaluate ctx
 				rhs = @rhs.evaluate ctx
-
-				assert("`#{@op}` takes two args of same type") { lhs.type == rhs.type }
-
-				res = @block.call lhs.val, rhs.val
-
-				assert("`#{@op}` must return True or False") { [true, false].include? res }
-				assert("`#{@op}` args type missmatch #{lhs.type}, expected: Integer, Natural, Bool or Text") { [Types::Integer, Types::Natural,
-												    Types::Bool, Types::Text].include? lhs.type }
-
-				Value.new res, Types::Bool
+				@block.call lhs, rhs
 			end
 		end
 
@@ -105,10 +91,7 @@ module Dhallish
 
 			def evaluate(ctx)
 				cond = @cond.evaluate ctx
-
-				assert("type error in `ìf .. then ... else ...`: expected Bool: `#{cond.type}`") { cond.type == Types::Bool }
-
-				if cond.val
+				if cond
 					@iftrue.evaluate ctx
 				else
 					@iffalse.evaluate ctx
@@ -132,9 +115,7 @@ module Dhallish
 			end
 
 			def evaluate(ctx)
-				val = ctx[@varname]
-				assert("undefined variable: `#{@varname}`") { !val.nil? }
-				val
+				ctx[@varname]
 			end
 		end
 
@@ -159,11 +140,10 @@ module Dhallish
 						str + part
 					else
 						val = part.evaluate ctx
-						assert("expected Text in Text interpolation") { val.type == Types::Text }
-						str + val.val.to_s
+						str + val
 					end
 				}
-				Value.new tmp, Types::Text
+				tmp
 			end
 		end
 
@@ -203,18 +183,8 @@ module Dhallish
 				vars.each { |elm|
 					varname, expected_type_ast, expr = elm
 					val = expr.evaluate newctx
-					if !expected_type_ast.nil?
-						exp_type = expected_type_ast.evaluate(ctx)
-						assert ("Annotated Expression is not a type") {exp_type.type.is_a? Types::Type}
-						if val.type.is_a? Types::Function and exp_type.val.is_a? Types::Function
-							val.type.restype = exp_type.val.restype
-							val.type.unres = exp_type.val.unres
-						end
-						assert ("Variable #{varname} has wrong type. Expected #{exp_type.val}") { val.type == exp_type.val }
-					end
 					newctx[varname] = val
 				}
-
 				inexpr.evaluate newctx
 			end
 		end
@@ -249,13 +219,7 @@ module Dhallish
 			end
 
 			def evaluate(ctx)
-				# nil is used as argument to Types::Function because we do not know the return type of this
-				# function at that point in type.
-
-				argtype = @argtype.evaluate ctx
-				assert("function argument type missmatch: #{argtype.type}") { argtype.type.is_a? Types::Type }
-
-				Value.new Function.new(@argname, @body, ctx), Types::Function.new(argtype.val, nil)
+				Function.new(@argname, @body, ctx)
 			end
 
 		end
@@ -309,12 +273,7 @@ module Dhallish
 			def evaluate(ctx)
 				lhs = @lhs.evaluate(ctx)
 				rhs = @rhs.evaluate(ctx)
-
-				assert ("Mismatching type for List Concatenation. Left Operand does not have a list type but #{lhs.type}") { lhs.type.is_a? Types::List }
-				assert ("Mismatching type for List Concatenation. Right Operand doesnot have a list type but #{rhs.type}") { rhs.type.is_a? Types::List }
-				assert ("#: Mismatching types. Left List hast Type List #{lhs.type}, right list has type #{rhs.type}") { lhs.type.type == rhs.type.type }
-
-				Value.new lhs.val + rhs.val, lhs.type
+				lhs + rhs
 			end
 		end
 
@@ -352,30 +311,11 @@ module Dhallish
 			end
 
 			def evaluate(ctx)
-				if @list.size == 0
-					assert ("Empty Lists are only allowed with type annotation") { not @type_node.nil? }
-					type_eval = @type_node.evaluate(ctx)
-					assert ("Given expression is not a type parameter") { type_eval.type.is_a? Types::Type }
-					Value.new [], (Types::List.new type_eval.val)
-				else
-					if not @type_node.nil?
-						type_eval = @type_node.evaluate(ctx)
-						assert ("Given expression is not a type parameter") { type_eval.type.is_a? Types::Type }
-						expected_type = type_eval.val
-					else
-						expected_type = nil
-					end
-					res = []
-					list.each_with_index { |node, idx|
-						elem = node.evaluate(ctx)
-						if expected_type.nil?
-							expected_type = elem.type
-						end
-						assert("List elements type mismatch: element 0 has type #{expected_type}, but element #{idx} has type #{elem.type}") { elem.type == expected_type }
-						res.append elem
-					}
-					Value.new res, (Types::List.new expected_type)
-				end
+				res = []
+				list.each { |node|
+					res.append node.evaluate(ctx)
+				}
+				res
 			end
 		end
 
@@ -400,12 +340,10 @@ module Dhallish
 			end
 
 			def evaluate(ctx)
-				expr = @expression.evaluate(ctx)
 				if @isSome
-					Value.new expr, (Types::Optional.new expr.type)
+					@expression.evaluate(ctx)
 				else
-					assert ("\"None\" expects a Type") { expr.type.is_a? Types::Type }
-					Value.new nil, (Types::Optional.new expr.val)
+					nil
 				end
 			end
 		end
@@ -428,17 +366,7 @@ module Dhallish
 			end
 
 			def evaluate(ctx)
-				type = @type.evaluate ctx
-				assert("type annotation expected a type as second argument: #{type.type}") { type.type.is_a? Types::Type }
-				res = @expr.evaluate ctx
-				if type.val.is_a? Types::Function and res.type.is_a? Types::Function
-					res.type.restype = type.val.restype
-					res.type.argtype = type.val.argtype
-					res.type.unres = type.val.unres
-				end
-				assert("type annotation missmatch: #{res.type} (expected: #{type.val})") { res.type == type.val }
-
-				return res
+				@expr.evaluate ctx
 			end
 		end
 
@@ -459,14 +387,10 @@ module Dhallish
 
 			def evaluate(ctx)
 				vals = {}
-				types = {}
 				@hash.each { |key, node|
-					val = node.evaluate ctx
-					vals[key] = val
-					types[key] = val.type
+					vals[key] = node.evaluate ctx
 				}
-
-				Value.new vals, Types::Record.new(types)
+				vals
 			end
 		end
 
@@ -490,12 +414,9 @@ module Dhallish
 			def evaluate(ctx)
 				types = {}
 				@hash.each { |key, node|
-					type = node.evaluate ctx
-					assert("only types are allowed in record-types") { type.type.is_a? Types::Type }
-					types[key] = type.val
+					types[key] = node.evaluate ctx
 				}
-
-				Value.new Types::Record.new(types), Types::Type.new
+				Types::Record.new types
 			end
 		end
 
@@ -516,11 +437,7 @@ module Dhallish
 
 			def evaluate(ctx)
 				rec = @rec.evaluate ctx
-				assert("`.` can only be used to access records") { rec.type.is_a? Types::Record }
-
-				val = rec.val[@key]
-				assert("no such key: `#{@key}`") { !val.nil? }
-				return val
+				rec[@key]
 			end
 		end
 
@@ -546,19 +463,11 @@ module Dhallish
 
 			def evaluate(ctx)
 				rec = @rec.evaluate ctx
-				assert("`.` can only be used to access records") { rec.type.is_a? Types::Record }
-
 				newrecvals = {}
-				newrectypes = {}
-
 				@keys.each { |key|
-					val = rec.val[key]
-					assert("key `#{key}` does not exist in record") { !val.nil? }
-					newrecvals[key] = val
-					newrectypes[key] = val.type
+					newrecvals[key] = rec[key]
 				}
-
-				Value.new newrecvals, Types::Record.new(newrectypes)
+				newrecvals
 			end
 		end
 
@@ -629,7 +538,7 @@ module Dhallish
 			def evaluate(ctx)
 				lhs = @lhs.evaluate(ctx)
 				rhs = @rhs.evaluate(ctx)
-				Value.new ::Dhallish::mergeRecordTypes(lhs.val, rhs.val), Types::Type.new
+				::Dhallish::mergeRecordTypes(lhs, rhs)
 			end
 		end
 
@@ -666,19 +575,16 @@ module Dhallish
 
 			def evaluate(ctx)
 				lhs = @lhs.evaluate(ctx)
-				assert ("argtype of function type is not a type but #{lhs.type}") { lhs.type.is_a? Types::Type }
 
-				if !type_var.nil? and lhs.val.is_a? Types::Type
-					newctx = Context.new(ctx)
-					newctx[type_var] = Value.new(Types::Unresolved.new(type_var), Types::Type.new)
-					rhs = @rhs.evaluate(newctx)
+				if !type_var.nil? and lhs.is_a? Types::Type
+					new_ctx = Context.new(ctx)
+					new_ctx[type_var] = Types::Unresolved.new(type_var)
+					rhs = @rhs.evaluate(new_ctx)
 				else
 					rhs = @rhs.evaluate(ctx)
 				end
 
-				assert ("target type of function type is not a type but #{rhs.type}") { rhs.type.is_a? Types::Type }
-
-				Value.new Types::Function.new(lhs.val, rhs.val, type_var), Types::Type.new
+				Types::Function.new(lhs, rhs, type_var)
 			end
 		end
 
@@ -737,13 +643,13 @@ module Dhallish
 				end
 
 				if @import_as_text
-					@buf = Value.new text, Types::Text
+					@buf = text
 					Types::Text
 				else
 					# treat as dhallish expression
 					d = Dhallish.new new_path
-					@buf = d.evaluate text
-					@buf.type
+					@buf, type = d.evaluate text
+					type
 				end
 			end
 
@@ -781,5 +687,23 @@ module Dhallish
 			end
 		end
 
+		class Literal_Node
+			attr_accessor :val
+			attr_accessor :type
+			
+			def initialize(val, type)
+				@val = val
+				@type = type
+			end
+			
+			def compute_type(ctx)
+				@type
+			end
+
+			def evaluate(ctx)
+				@val
+			end
+		end
+
 	end
 end
diff --git a/lib/dhallish.rb b/lib/dhallish.rb
index 1e15e1f..0680fdf 100644
--- a/lib/dhallish.rb
+++ b/lib/dhallish.rb
@@ -34,7 +34,7 @@ module Dhallish
 			type = ast.compute_type typectx
 			puts type
 
-			return ast.evaluate ctx
+			return [ast.evaluate(ctx), type]
 		end
 
 	end
-- 
GitLab