#--------------------------------------------------------------------# expression.rb - IDL Expression classes## Author: Martin Corino## This program is free software; you can redistribute it and/or# modify it under the terms of the RIDL LICENSE which is# included with this program.## Copyright (c) Remedy IT Expertise BV# Chamber of commerce Rotterdam nr.276339, The Netherlands#--------------------------------------------------------------------require'ridl/node'moduleIDLclassExpressionattr_reader:idltypeattr_reader:valuedeftypename;@idltype.typename;enddefis_template?falseenddefinstantiate(_context)selfendclassValue<Expressiondefinitialize(type,val)@idltype=type@value=@idltype.narrow(val)endendclassScopedName<Expressionattr_reader:nodedefinitialize(node)if$DEBUGunlessIDL::AST::Const===node||(IDL::AST::TemplateParam===node&&node.idltype.is_a?(IDL::Type::Const))raiseRuntimeError,"#{node.scoped_name} must be constant: #{node.class.name}."endend@node=node@idltype=node.idltype@value=@idltype.narrow(node.value)unlessnode.is_template?enddefis_template?@node.is_template?enddefinstantiate(_context)ifself.is_template?cp=IDL::AST::TemplateParam.concrete_param(_context,@node)cp.is_a?(Expression)?cp:ScopedName.new(cp)elseselfendenddefis_node?(node_class)@node.is_a?(node_class)enddefresolved_node@nodeendendclassEnumerator<Expressionattr_reader:nodedefinitialize(node)if$DEBUGifnotIDL::AST::Enumerator===noderaiseRuntimeError,"#{node.scoped_name} must be enumerator: #{node.class.name}."endend@node=node@idltype=node.idltype@value=node.valueendendclassOperation<ExpressionNUMBER_OF_OPERANDS=nilattr_reader:operandsdefinitialize(*_operands)n=self.class::NUMBER_OF_OPERANDSif_operands.size!=nraiseRuntimeError,format("%s must receive %d operand%s.",self.typename,n,if(n>1)then"s"else""end)endunless_operands.any?{|o|o.is_template?}@idltype=self.class.suite_type(*(_operands.collect{|o|o.idltype.resolved_type}))@value=calculate(*(_operands.collect{|o|o.value}))else@idltype=nil@value=nilend@operands=_operandsself.set_typeenddefis_template?@operands.any?{|o|o.is_template?}enddefinstantiate(_context)self.is_template??self.class.new(*@operands.collect{|o|o.instantiate(_context)}):selfenddefOperation.suite_type(*types)types.eachdo|t|ifnotself::Applicable.include?t.classraiseRuntimeError,"#{self.name} cannot be applicable for #{t.typename}"endendret=niltypes=types.collect{|t|t.class}self::Applicable.eachdo|t|iftypes.include?tret=tbreakendendretenddefset_typeendclassUnary<OperationNUMBER_OF_OPERANDS=1Applicable=nilend#of class UnaryclassInteger2<OperationNUMBER_OF_OPERANDS=2Applicable=[IDL::Type::LongLong,IDL::Type::ULongLong,IDL::Type::Long,IDL::Type::ULong,IDL::Type::Short,IDL::Type::UShort,IDL::Type::Octet]defInteger2.suite_sign(_t,_v)[[IDL::Type::LongLong,IDL::Type::ULongLong],[IDL::Type::Long,IDL::Type::ULong],[IDL::Type::Short,IDL::Type::UShort]].eachdo|t|nextunlesst.include?_treturn(if_v<0thent[0]elset[1]end)endenddefset_typeifInteger2::Applicable.include?@idltype@idltype=self.class.suite_sign(@idltype,@value)endendendclassBoolean2<Integer2Applicable=[IDL::Type::Boolean]+Integer2::ApplicabledefBoolean2.checktype(t1,t2)superclass.checktype(*types)t=IDL::Type::Booleanif(t1==t&&t2!=t)or(t1!=t&&t2==t)raiseRuntimeError,"#{self.name} about #{t1.typename} and #{t2.typename} is illegal."endendendclassFloat2<Integer2Applicable=[IDL::Type::LongDouble,IDL::Type::Double,IDL::Type::Float,IDL::Type::Fixed]+Integer2::ApplicabledefFloat2.checktype(t1,t2)superclass.checktype(*types)# it's expected that Double, LongDouble is a Float.s1,s2=IDL::Type::Float,IDL::Type::Fixedif(t1===s1&&t2===s2)or(t1===s2&&t2===s1)raiseRuntimeError,"#{self.name} about #{t1.typename} and #{t2.typename} is illegal."endendendclassUnaryPlus<UnaryApplicable=Float2::Applicabledefcalculate(op)opendendclassUnaryMinus<UnaryApplicable=Float2::Applicabledefcalculate(op)-openddefset_type@idltype=Integer2.suite_sign(@idltype,@value)endendclassUnaryNot<UnaryApplicable=Integer2::Applicabledefcalculate(op)if@idltype.is_unsigned?()(2**@idltype.bits-1)-opelse~opendendendclassOr<Boolean2defcalculate(lop,rop);lop|rop;endendclassAnd<Boolean2defcalculate(lop,rop);lop&rop;endendclassXor<Boolean2defcalculate(lop,rop);lop^rop;endendclassShift<Integer2protecteddefcheck_rop(rop)ifnot(0...64)===ropraiseRuntimeError,"right operand for shift must be in the range 0 <= right operand < 64: #{rop}."endendendclassLShift<Shiftdefcalculate(lop,rop)check_rop(rop)lop<<ropendendclassRShift<Shiftdefcalculate(lop,rop)check_rop(rop)lop>>ropendendclassAdd<Float2defcalculate(lop,rop);lop+rop;endendclassMinus<Float2defcalculate(lop,rop);lop-rop;endendclassMult<Float2defcalculate(lop,rop);lop*rop;endendclassDiv<Float2defcalculate(lop,rop);lop/rop;endendclassMod<Integer2defcalculate(lop,rop);lop%rop;endendend#of class Operationend#of class Expressionend