Type checking and type conversions in sip-router ------------------------------------------------- Type checking and conversion depend on the operators used. Type checking is done _only_ on startup (at "compile" time) and it aims to be quite strict (as much as possible while still supporting avps or pvars with unknown dynamic types). >From the type conversion of their operands point of view, we have 4 types of operators: integer operators, which require integer arguments, string operators with require string arguments, mixed operators, which can work with different types and special operators (only "defined" for now). intop: /, *, - , ||, &&, &, |, <, >, <=, >=, a.s.o. strop: strlen, strempty, eq, ne, a.s.o. mixed ops: +, ==, != special op: defined 1. "Compile" Time (sip-router start time) ----------------------------------------- The integer only and string only operators require that all of their operands have the type of the operator: intop operands (o1 o2): int str unknown int OK err OK str err err err unknown OK err OK strop operands (o1 o2): int str unknown int err err err str err OK OK unknown err OK OK The mixed operators require that all of their operands have the _same_ type, with the exception of '+' which will allow an int operand on the right side, even if the left side is a string. mixed ops: +: int str unknown int OK err OK str OK* OK OK unknown OK OK OK ==/!=: int str unkown int OK err OK str err OK OK unkown OK OK OK 2. Runtime ----------- The main difference is that we don't have unknown types anymore, since we can resolve the avps & pvars => everything has a type: int, str or undefined. everything is allowed (no error), by automatically converting to the type required by the operator. All integer operators convert their operands to int and all string operators to str. Conversion table: (int I, str S) int str:"I" str:S undefined (int) I I 0 0 where str:"I" means the str is an interger between quotes, and str:S means the string is not number. int str undefined (str) "I" S "" Special cases: +, == and != The "mixed" operators that support both int & str in the same time try to determine the type of the operation by looking at the left operand. If the left operand is int, the right one will be converted to int too (using the above conversion table) and then the operation will be performed Same for string. o1 o2 => o1 (type_of(o1)) (o2). undef in the left side is handled in a special way: for == and !=, the type is taken from the right operand: undef o2 => (type_of(o2)) undef o2 For +, undef in the left side is considered to be string: undef <+> o2 => (str) undef (str)o2 => "" (str)o2 => (str)o2 ==/!= i2 s2 undef i1 i1 i2 i1 (int)s2 i1 0 s1 s1 (str)i2 s1 s2 s1 "" undef 0 i2 "" s2 "" "" (where is the integer version of the operator and is the string version) + i2 s2 undef i1 i1 i2 i1 (int)s2 i1 0 s1 s1 (str)i2 s1 s2 s1 "" undef "" (str)i2 "" s2 "" "" ( is interger +, is string concat) Note: the undef in the left side case is handled differently for +. == table of truth: == int str:"" str:"I2" str:S undef int I1==I2 I1==0 I1==I2 I1==0 I1==0 str S1=="I1" S1=="" S1=="I2" S1==S S1=="" undef 0==I2 true ""=="I2" ""==S true 3. Converting to int or string ------------------------------- For now we don't have any explicit conversion operators (might be introduced), so we have to reuse '+'. Converting $v to int: (0 + $v) Converting $v to str: ("" + $v)