Author: mdiep
Date: Sat Aug 20 11:14:56 2005
New Revision: 9009

Added:
   trunk/languages/tcl/lib/tclfunc.pir
Modified:
   trunk/MANIFEST
   trunk/config/gen/makefiles/tcl.in
   trunk/languages/tcl/lib/expression.pir
   trunk/languages/tcl/tcl.pir_template
   trunk/languages/tcl/tcl.pl
Log:
- Add a TclFunc class (move all the expr function logic there)
- Get rid of the FUNC constant
- Use TclFunc objects to make functions operands


Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST      (original)
+++ trunk/MANIFEST      Sat Aug 20 11:14:56 2005
@@ -1427,6 +1427,7 @@ languages/tcl/lib/string_to_list.pir    
 languages/tcl/lib/string.pir                      [tcl]
 languages/tcl/lib/tclcommand.pir                  [tcl]
 languages/tcl/lib/tclconst.pir                    [tcl]
+languages/tcl/lib/tclfunc.pir                     [tcl]
 languages/tcl/lib/tclvar.pir                      [tcl]
 languages/tcl/lib/tclword.pir                     [tcl]
 languages/tcl/lib/tcl.p6r                         [tcl]

Modified: trunk/config/gen/makefiles/tcl.in
==============================================================================
--- trunk/config/gen/makefiles/tcl.in   (original)
+++ trunk/config/gen/makefiles/tcl.in   Sat Aug 20 11:14:56 2005
@@ -74,7 +74,7 @@ lib${slash}variables.pir \
 tcl.pir_template \
 tcl.pl
 
-tcl.pbc: pmcs lib${slash}tcllib.pbc lib${slash}tclcommand.pbc 
lib${slash}tclconst.pbc lib${slash}tclvar.pbc lib${slash}tclword.pbc tcl.pir
+tcl.pbc: pmcs lib${slash}tcllib.pbc lib${slash}tclcommand.pbc 
lib${slash}tclconst.pbc lib${slash}tclfunc.pbc lib${slash}tclvar.pbc 
lib${slash}tclword.pbc tcl.pir
        $(PARROT) --output=tcl.pbc tcl.pir
 
 pmcs:
@@ -98,6 +98,9 @@ lib${slash}tclcommand.pbc: lib${slash}tc
 lib${slash}tclconst.pbc: lib${slash}tclconst.pir
        $(PARROT) --output=$(LIBPATH)${slash}tclconst.pbc 
$(LIBPATH)${slash}tclconst.pir
 
+lib${slash}tclfunc.pbc: lib${slash}tclfunc.pir
+       $(PARROT) --output=$(LIBPATH)${slash}tclfunc.pbc 
$(LIBPATH)${slash}tclfunc.pir
+
 lib${slash}tclvar.pbc: lib${slash}tclvar.pir
        $(PARROT) --output=$(LIBPATH)${slash}tclvar.pbc 
$(LIBPATH)${slash}tclvar.pir
 

Modified: trunk/languages/tcl/lib/expression.pir
==============================================================================
--- trunk/languages/tcl/lib/expression.pir      (original)
+++ trunk/languages/tcl/lib/expression.pir      Sat Aug 20 11:14:56 2005
@@ -133,16 +133,13 @@ get_function:
   # Does the string of characters here match one of our pre-defined
   # functions? If so, put that function on the stack.
   .local pmc func
-  .local pmc result
 
-  (op_length,func,result) = __expr_get_function(expr,chunk_start)
+  (op_length,func) = __expr_get_function(expr,chunk_start)
   if op_length == 0 goto get_operator
   chunk = new TclList
-  chunk[0] = FUNC
+  chunk[0] = OPERAND
   chunk[1] = func
-  chunk[2] = -1 # functions trump operands, for now.
   push chunks, chunk
-  push chunks, result
   chunk_start += op_length
   dec chunk_start
   goto chunk_loop
@@ -266,7 +263,6 @@ converter_loop:
   if $I2 == OPERAND goto converter_next
   if $I2 == CHUNK   goto converter_next
   if $I2 == OP   goto is_opfunc
-  if $I2 == FUNC goto is_opfunc # XXX should eventually go away as we make 
functions part of "CHUNK", above.
 
   # Should never be reached (XXX then shouldn't we die horribly?)
   goto converter_next 
@@ -356,7 +352,6 @@ stack_evaluator:
 
  # move all non op non funcs to the value stack
  if type == OP goto do_op
- if type == FUNC goto do_op
  $P0 = chunk[1]
  $P0 = $P0."interpret"()
  chunk[1] = $P0
@@ -367,8 +362,8 @@ do_op:
   # right now, we assume binary ops. Later, each op will define the
   # number of and type of ops it takes, and we will respect it.
 
-  .local int func
-  func = chunk[1]
+  .local int op
+  op = chunk[1]
 
   # XXX assume all operands take two args.
   .local pmc r_arg
@@ -378,44 +373,28 @@ do_op:
   l_arg = pop result_stack
   l_arg = l_arg[1]
 
-  if func >= FUNCTION_ABS goto func_list
   r_arg = pop result_stack
   r_arg = r_arg[1]
 
   # Is there a more efficient way to do this dispatch?
-  if func == OPERATOR_MUL goto op_mul
-  if func == OPERATOR_DIV goto op_div
-  if func == OPERATOR_MOD goto op_mod
-  if func == OPERATOR_PLUS goto op_plus
-  if func == OPERATOR_MINUS goto op_minus
-  if func == OPERATOR_SHL goto op_shl
-  if func == OPERATOR_SHR goto op_shr
-  if func == OPERATOR_LT goto op_lt
-  if func == OPERATOR_GT goto op_gt
-  if func == OPERATOR_LTE goto op_lte
-  if func == OPERATOR_GTE goto op_gte
-  if func == OPERATOR_EQUAL goto op_equal
-  if func == OPERATOR_UNEQUAL goto op_unequal
-  if func == OPERATOR_BITAND goto op_bitand
-  if func == OPERATOR_BITXOR goto op_bitxor
-  if func == OPERATOR_BITOR goto op_bitor
-  if func == OPERATOR_NE goto op_ne
-  if func == OPERATOR_EQ goto op_eq
-func_list: 
-  if func == FUNCTION_ABS goto func_abs
-  if func == FUNCTION_ACOS goto func_acos
-  if func == FUNCTION_ASIN goto func_asin
-  if func == FUNCTION_ATAN goto func_atan
-  if func == FUNCTION_COS goto func_cos
-  if func == FUNCTION_COSH goto func_cosh
-  if func == FUNCTION_EXP goto func_exp
-  if func == FUNCTION_LOG goto func_log
-  if func == FUNCTION_LOG10 goto func_log10
-  if func == FUNCTION_SIN goto func_sin
-  if func == FUNCTION_SINH goto func_sinh
-  if func == FUNCTION_SQRT goto func_sqrt
-  if func == FUNCTION_TAN goto func_tan
-  if func == FUNCTION_TANH goto func_tanh
+  if op == OPERATOR_MUL goto op_mul
+  if op == OPERATOR_DIV goto op_div
+  if op == OPERATOR_MOD goto op_mod
+  if op == OPERATOR_PLUS goto op_plus
+  if op == OPERATOR_MINUS goto op_minus
+  if op == OPERATOR_SHL goto op_shl
+  if op == OPERATOR_SHR goto op_shr
+  if op == OPERATOR_LT goto op_lt
+  if op == OPERATOR_GT goto op_gt
+  if op == OPERATOR_LTE goto op_lte
+  if op == OPERATOR_GTE goto op_gte
+  if op == OPERATOR_EQUAL goto op_equal
+  if op == OPERATOR_UNEQUAL goto op_unequal
+  if op == OPERATOR_BITAND goto op_bitand
+  if op == OPERATOR_BITXOR goto op_bitxor
+  if op == OPERATOR_BITOR goto op_bitor
+  if op == OPERATOR_NE goto op_ne
+  if op == OPERATOR_EQ goto op_eq
 
   #error_S = "invalid function lookup returned"
   goto die_horribly
@@ -493,78 +472,7 @@ op_eq:
   $S1 = r_arg
   if $S0 == $S1 goto done_op
   op_result = 0
-  goto done_op
-func_abs:
-  # XXX This isn't int only, izzit?
-  $I0 = l_arg
-  $I1 = abs $I0
-  op_result = $I1
-  goto done_op
-func_acos:
-  $N0 = l_arg
-  $N1 = acos $N0
-  op_result = $N1
-  goto done_op
-func_asin:
-  $N0 = l_arg
-  $N1 = asin $N0
-  op_result = $N1
-  goto done_op
-func_atan:
-  $N0 = l_arg
-  $N1 = atan $N0
-  op_result = $N1
-  goto done_op
-func_cos:
-  $N0 = l_arg
-  $N1 = cos $N0
-  op_result = $N1
-  goto done_op
-func_cosh:
-  $N0 = l_arg
-  $N1 = cosh $N0
-  op_result = $N1
-  goto done_op
-func_exp:
-  $N0 = l_arg
-  $N1 = exp $N0
-  op_result = $N1
-  goto done_op
-func_log:
-  $N0 = l_arg
-  $N1 = ln $N0
-  op_result = $N1
-  goto done_op
-func_log10:
-  $N0 = l_arg
-  $N1 = log10 $N0
-  op_result = $N1
-  goto done_op
-func_sin:
-  $N0 = l_arg
-  $N1 = sin $N0
-  op_result = $N1
-  goto done_op
-func_sinh:
-  $N0 = l_arg
-  $N1 = sinh $N0
-  op_result = $N1
-  goto done_op
-func_sqrt:
-  $N0 = l_arg
-  $N1 = sqrt $N0
-  op_result = $N1
-  goto done_op
-func_tan:
-  $N0 = l_arg
-  $N1 = tan $N0
-  op_result = $N1
-  goto done_op
-func_tanh:
-  $N0 = l_arg
-  $N1 = tanh $N0
-  op_result = $N1
-  # fallthrough to done_op
+  # goto done_op
 
 done_op:
   $P5 = new FixedPMCArray
@@ -704,9 +612,13 @@ loop_done:
   $P1 = find_global "_Tcl", "functions"
   
   func = $P1[$S0]
-  if_null func, fail 
-  $I0 = typeof func
-  if $I0 == .Undef goto fail
+  if_null func, fail
+  
+  $I0 = find_type "TclFunc"
+  func = new $I0
+  $P0 = new String
+  $P0 = $S0
+  setattribute func, "TclFunc\x00name", $P0
 
   # and the operand is what's between the ()'s - get the result
   # of /that/ expression and return it.
@@ -719,26 +631,21 @@ loop_done:
   len_operand = $I1
 
   $S1 = substr expr, start_paren_pos, len_operand
-  # XXX should be checking return value here.
-  ($I9,operand) = __expression_parse($S1)  
-  ($I9,operand) = __expression_interpret(operand)  
-  $P10 = new FixedPMCArray
-  $P10 = 2
-  $P10[0] = OPERAND
-  $P10[1] = operand
-  operand = $P10
+  ($I9,operand) = __expression_parse($S1) 
   if $I9 == TCL_ERROR goto fail
+  
+  setattribute func, "TclFunc\x00argument", operand
 
-  len =  start_paren_pos + len_operand
+  len = start_paren_pos + len_operand
   inc len
-  len = len - start
+  len -= start
   goto done
 
 fail:
   len = 0
 
 done:
-  .return(len,func,operand)
+  .return(len,func)
 .end
 
 =head2 _Tcl::__get_call_level

Added: trunk/languages/tcl/lib/tclfunc.pir
==============================================================================
--- (empty file)
+++ trunk/languages/tcl/lib/tclfunc.pir Sat Aug 20 11:14:56 2005
@@ -0,0 +1,160 @@
+.namespace [ "TclFunc" ]
+
+.HLL "Tcl", "tcl_group"
+
+# return codes
+ .const int TCL_OK = 0
+ .const int TCL_ERROR = 1
+ .const int TCL_RETURN = 2
+ .const int TCL_BREAK = 3
+ .const int TCL_CONTINUE = 4
+
+# functions
+ .const int FUNCTION_ABS    = 53
+ .const int FUNCTION_ACOS   = 54
+ .const int FUNCTION_ASIN   = 55
+ .const int FUNCTION_ATAN   = 56
+ .const int FUNCTION_COS    = 57
+ .const int FUNCTION_COSH   = 58
+ .const int FUNCTION_EXP    = 59
+ .const int FUNCTION_LOG    = 60
+ .const int FUNCTION_LOG10  = 61
+ .const int FUNCTION_ROUND  = 62
+ .const int FUNCTION_SIN    = 63
+ .const int FUNCTION_SINH   = 64
+ .const int FUNCTION_SQRT   = 65
+ .const int FUNCTION_TAN    = 66
+ .const int FUNCTION_TANH   = 67
+ .const int FUNCTION_RAND   = 68
+
+=head2 __class_init
+
+Define the attributes required for the class.
+
+=cut
+
+.sub __class_init @LOAD
+  $P0 = newclass "TclFunc"
+  addattribute $P0, "argument"
+  addattribute $P0, "name"
+.end
+
+=head2 __init
+
+Initialize the attributes for an instance of the class
+
+=cut
+
+.sub __init method
+  $P0 = new TclString
+  setattribute self, "TclFunc\x00name", $P0
+  $P0 = new TclString
+  setattribute self, "TclFunc\x00argument", $P0
+.end
+
+.sub interpret method
+  .local pmc retval
+  .local int return_type
+  # assigning a $Nx will change this to a TclFloat
+  retval      = new TclInt
+  return_type = TCL_OK
+  
+  .local pmc funcs, expr_interpret
+  funcs = find_global "_Tcl", "functions"
+  expr_interpret = find_global "_Tcl", "__expression_interpret"
+  
+  .local pmc arg, name
+  arg  = getattribute self, "TclFunc\x00argument"
+  (return_type, retval) = expr_interpret(arg)
+  if return_type == TCL_ERROR goto done
+  arg  = retval
+  name = getattribute self, "TclFunc\x00name"
+  
+  $I0 = funcs[name]
+  if $I0 == FUNCTION_ABS goto func_abs
+  if $I0 == FUNCTION_ACOS goto func_acos
+  if $I0 == FUNCTION_ASIN goto func_asin
+  if $I0 == FUNCTION_ATAN goto func_atan
+  if $I0 == FUNCTION_COS goto func_cos
+  if $I0 == FUNCTION_COSH goto func_cosh
+  if $I0 == FUNCTION_EXP goto func_exp
+  if $I0 == FUNCTION_LOG goto func_log
+  if $I0 == FUNCTION_LOG10 goto func_log10
+  if $I0 == FUNCTION_SIN goto func_sin
+  if $I0 == FUNCTION_SINH goto func_sinh
+  if $I0 == FUNCTION_SQRT goto func_sqrt
+  if $I0 == FUNCTION_TAN goto func_tan
+  if $I0 == FUNCTION_TANH goto func_tanh
+  
+func_abs:
+  retval = abs arg
+  goto done
+func_acos:
+  $N0 = arg
+  $N1 = acos $N0
+  retval = $N1
+  goto done
+func_asin:
+  $N0 = arg
+  $N1 = asin $N0
+  retval = $N1
+  goto done
+func_atan:
+  $N0 = arg
+  $N1 = atan $N0
+  retval = $N1
+  goto done
+func_cos:
+  $N0 = arg
+  $N1 = cos $N0
+  retval = $N1
+  goto done
+func_cosh:
+  $N0 = arg
+  $N1 = cosh $N0
+  retval = $N1
+  goto done
+func_exp:
+  $N0 = arg
+  $N1 = exp $N0
+  retval = $N1
+  goto done
+func_log:
+  $N0 = arg
+  $N1 = ln $N0
+  retval = $N1
+  goto done
+func_log10:
+  $N0 = arg
+  $N1 = log10 $N0
+  retval = $N1
+  goto done
+func_sin:
+  $N0 = arg
+  $N1 = sin $N0
+  retval = $N1
+  goto done
+func_sinh:
+  $N0 = arg
+  $N1 = sinh $N0
+  retval = $N1
+  goto done
+func_sqrt:
+  $N0 = arg
+  $N1 = sqrt $N0
+  retval = $N1
+  goto done
+func_tan:
+  $N0 = arg
+  $N1 = tan $N0
+  retval = $N1
+  goto done
+func_tanh:
+  $N0 = arg
+  $N1 = tanh $N0
+  retval = $N1
+  # goto done
+
+done:
+  .return(return_type, retval)
+.end

Modified: trunk/languages/tcl/tcl.pir_template
==============================================================================
--- trunk/languages/tcl/tcl.pir_template        (original)
+++ trunk/languages/tcl/tcl.pir_template        Sat Aug 20 11:14:56 2005
@@ -24,7 +24,6 @@ providing a compreg-compatible method.
 # so there's no conflict.
 
   .const int OP      = 20
-  .const int FUNC    = 21
   .const int OPERAND = 11
  
   # Still not sure if these are going to be useful
@@ -86,6 +85,7 @@ providing a compreg-compatible method.
   # Load any dependant libraries.
   load_bytecode "languages/tcl/lib/tclcommand.pbc"
   load_bytecode "languages/tcl/lib/tclconst.pbc"
+  load_bytecode "languages/tcl/lib/tclfunc.pbc"
   load_bytecode "languages/tcl/lib/tclvar.pbc"
   load_bytecode "languages/tcl/lib/tclword.pbc"
   load_bytecode "library/Data/Escape.pbc"

Modified: trunk/languages/tcl/tcl.pl
==============================================================================
--- trunk/languages/tcl/tcl.pl  (original)
+++ trunk/languages/tcl/tcl.pl  Sat Aug 20 11:14:56 2005
@@ -33,7 +33,7 @@ my @commands = grep {s/\.pir$//} @cmd_fi
 
 my $lib_dir = "lib";
 opendir(LIBDIR,$lib_dir) or die;
-my @libs = map {"$lib_dir/$_"} grep {m/\.pir$/} grep {! 
m/^tcl(lib|command|const|var|word).pir$/} readdir(LIBDIR);
+my @libs = map {"$lib_dir/$_"} grep {m/\.pir$/} grep {! 
m/^tcl(lib|command|const|func|var|word).pir$/} readdir(LIBDIR);
 closedir(LIBDIR);
 
 my $includes;

Reply via email to