# proc decr {varName {decrement 1}} { # upvar 1 $varName var # incr var [expr {-$decrement}] # } # set a 10 # decr a 2 # puts $a .pragma n_operators 1 # set varName ?value? .sub 'set' # builtin .param string varName .param pmc value :optional .param int has_value :opt_flag $P0 = getinterp # these 2 lines would make a nice $P1 = $P0['lexpad'; 1] # caller_pad $P1 opcode if has_value goto set_it value = $P1[varName] unless null value goto ret_it value = new .Undef set_it: $P1[varName] = value ret_it: .return (value) .end # upvar ?level? otherVar myVar ?otherVar myVar ...? .sub 'upvar' # builtin .param int level .param string otherVar # TODO loop over otherVar/myVar pairs .param string myVar # by flattening args $P0 = getinterp $P1 = $P0['lexpad'; 1] # caller, where 'myVar' is inc level # we do outer on behalf of caller $P2 = $P0['lexpad'; level] # the upmyVar # TODO loop here $P3 = $P2[otherVar] $P1[myVar] = $P3 .end # incr varName ?increment? .sub 'incr' # builtin .param string varName .param pmc increment :optional .param int has_increment :opt_flag $P0 = getinterp $P1 = $P0['lexpad'; 1] $P2 = $P1[varName] .lex 'increment', increment if has_increment goto increment_is_set increment = new .Integer increment = 1 increment_is_set: $P2 += increment .end # puts ?-nonewline? ?channelId? string .sub 'puts' # builtin .param pmc what # TODO options, channel print what print "\n" # unless -nonewline .end # user proc .sub 'decr' .param pmc varName .param pmc decrement :optional .param int has_decrement :opt_flag .lex 'varName', varName .lex 'decrement', decrement if has_decrement goto decrement_is_set decrement = new .Integer decrement = 1 decrement_is_set: $P0 = expr_01() .local pmc var .lex 'var', var 'upvar'(1, varName, 'var') 'incr'('var', $P0) .end # generated expr code .sub 'expr_01' :outer('decr') $P0 = find_lex 'decrement' $P1 = neg $P0 .return ($P1) .end .sub 'main' :main .local pmc a .lex 'a', a 'set'('a', '10') # could likely be optimized to 'set'('a', 10) 'decr'('a', '2') 'puts'(a) .end # TODO future # 'set', 'incr' ... could be inline, *if* the compiler never compiled # 'proc set ...', ... # the compiler probably could use a hash: # if %compiler_saw['set'] # compile_to_function ... # else # compile_inlined ...