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