class Kalculator::Validator
Public Class Methods
new(type_source)
click to toggle source
# File lib/kalculator/validator.rb, line 9 def initialize(type_source) @type_source = type_source #e stores built in function type data #last index is ALWAYS the return type, and types before that are types of children from left to right e = { "contains" => [Collection.new(Object), Object, Bool], "count" => [List.new(Object), Number], "date" => [String.new, Time], "max"=> [Number,Number,Number], "min" => [Number,Number,Number], "sum" => [List.new(Number), Number] #this only accepts number Lists } @environment = e.merge(type_source.toHash) end
Public Instance Methods
!=(_, left, right, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 118 def !=(_, left, right, metadata) leftType = validate(left) if(leftType==validate(right)) return Bool end raise TypeError.new(metadata), "not comparing two of the same comparable types" end
*(_, left, right, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 62 def *(_, left, right, metadata) leftType = validate(left) if((leftType==validate(right)) and leftType <=Number) return leftType end raise TypeError.new(metadata), "not operating on two of the same Number types" end
+(_, left, right, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 46 def +(_, left, right, metadata) leftType = validate(left) if((leftType==validate(right)) and leftType <=Number) return leftType end raise TypeError.new(metadata), "not operating on two of the same Number types" end
-(_, left, right, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 54 def -(_, left, right, metadata) leftType = validate(left) if((leftType==validate(right)) and leftType <=Number) return leftType end raise TypeError.new(metadata), "not operating on two of the same Number types" end
/(_, left, right, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 70 def /(_, left, right, metadata) leftType = validate(left) if((leftType==validate(right)) and leftType <=Number) return leftType end raise TypeError.new(metadata), "not operating on two of the same Number types" end
<(_, left, right, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 94 def <(_, left, right, metadata) leftType = validate(left) if((leftType==validate(right)) and leftType<= Comparable) return Bool end raise TypeError.new(metadata), "not comparing two of the same types" end
<=(_, left, right, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 102 def <=(_, left, right, metadata) leftType = validate(left) if((leftType==validate(right)) and leftType<= Comparable) return Bool end raise TypeError.new(metadata), "not comparing two of the same comparable types" end
==(_, left, right, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 110 def ==(_, left, right, metadata) leftType = validate(left) if(leftType==validate(right)) return Bool end raise TypeError.new(metadata), "not comparing two of the same comparable types" end
>(_, left, right, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 78 def >(_, left, right, metadata) leftType = validate(left) if((leftType==validate(right)) and leftType<= Comparable) return Bool end raise TypeError.new(metadata), "not comparing two of the same comparable types" end
>=(_, left, right, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 86 def >=(_, left, right, metadata) leftType = validate(left) if((leftType==validate(right)) and leftType<= Comparable) return Bool end raise TypeError.new(metadata), "not comparing two of the same comparable types" end
access(_,identifier,object, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 28 def access(_,identifier,object, metadata) objectType = validate(object) if((objectType.is_a?(MappedObject))) if(objectType.hash.key?(identifier)) attribute =objectType.hash[identifier] if(attribute.is_a?(Pointer)) attribute = @environment[attribute.p] #if the attribute is a pointer find an add end if(attribute.is_a?(Kalculator::AnonymousPointer)) attribute = attribute.p end return attribute end raise UndefinedVariableError.new(metadata), "object #{objectType} doesn't have type attribute #{identifier}" end raise TypeError.new(metadata), "trying to access something that isn't an object" end
and(_, left, right, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 126 def and(_, left, right, metadata) if(validate(left)<=Bool and validate(right)<=Bool) return Bool end raise TypeError.new(metadata), "not comparing (AND) two BOOL types" end
boolean(_, boolean, type, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 140 def boolean(_, boolean, type, metadata) return Bool end
exists(_, variable, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 144 def exists(_, variable, metadata) return Bool end
fn_call(_, fn_name, expressions, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 148 def fn_call(_, fn_name, expressions, metadata) #compare individually to make sure it is a subclass or class ex =expressions.map{|expression| validate(expression) } raise UndefinedVariableError.new(metadata), "undefined variable #{fn_name}" unless @environment.key?(fn_name) argumentMatch = ex.zip(@environment[fn_name]).all? do |(arg_type, expected_type)| begin arg_type <= expected_type rescue begin expected_type >= arg_type rescue false end end end if(argumentMatch) # make sure each element is related to corresponding element in the funcion params if(fn_name == "max" or fn_name == "min") #add functions here where output type depends on input type and all types must be exact same ie. max(Percent,Percent) => Percent max(Number,Percent)=> Error max(Number,Number)=>Number #check all expressions are same cmptype = ex[0] if( ex.all?{|t| t == cmptype}) return cmptype end raise TypeError.new(metadata), "specialized function type error" end #add other specialized functions here if(fn_name == "contains") #generic function in the format List<E>, E => ReturnType if(ex[0].generic_type?(ex[1])) return @environment[fn_name][@environment[fn_name].size - 1] end raise TypeError.new(metadata), "generic function type error" end return @environment[fn_name][@environment[fn_name].size - 1] end raise TypeError.new(metadata), "function type error" end
if(_, condition, true_clause, false_clause, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 183 def if(_, condition, true_clause, false_clause, metadata) conditionType = validate(condition) if(conditionType <= Object and validate(true_clause)==validate(false_clause)) return validate(true_clause) end raise TypeError.new(metadata), "if statement type error" end
list(_, expressions, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 191 def list(_, expressions, metadata) ex =expressions.map{|expression| validate(expression) } cmptype = ex[0] if( ex.all?{|t| t == cmptype}) return List.new(cmptype) end raise TypeError.new(metadata), "list type error" end
not(_, expression, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 202 def not(_, expression, metadata) if(validate(expression) ==Bool) return Bool end raise TypeError.new(metadata), "NOT expression type error" end
null(_, _, type, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 210 def null(_, _, type, metadata) return type end
number(_, number, type, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 214 def number(_, number, type, metadata) return type end
or(_, left, right, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 133 def or(_, left, right, metadata) if(validate(left)<=Bool and validate(right)<=Bool) return Bool end raise TypeError.new(metadata), "not comparing (OR) two BOOL types" end
percent(_, percent, type, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 218 def percent(_, percent, type, metadata) return type end
string(_, string, type, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 222 def string(_, string, type, metadata) return type end
validate(ast)
click to toggle source
# File lib/kalculator/validator.rb, line 23 def validate(ast) send(ast.first, *ast) end
variable(_, name, metadata)
click to toggle source
# File lib/kalculator/validator.rb, line 226 def variable(_, name, metadata) raise UndefinedVariableError.new(metadata), "undefined variable #{name}" unless @environment.key?(name) variable_type = @environment[name] if(variable_type.is_a?(Pointer)) variable_type = @environment[variable_type.p] #if the variable you are accessing is a pointer, then return the type of the variable it is pointing to end if(variable_type.is_a?(Kalculator::AnonymousPointer)) variable_type = variable_type.p end return variable_type end