Check-in [dfc7885448]
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Allow IMPURE values to builtin mathfuncs
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: dfc7885448d6684561015006db5569c0c487a7225b9838ebb98bd3cd2af94042
User & Date: kbk 2018-11-01 22:04:52
Context
2018-11-27
03:07
Fix bug in finding variable names among the args to 'regexp' check-in: 6311170b65 user: kbk tags: trunk
2018-11-26
08:35
merge trunk check-in: 45f62a2c25 user: dkf tags: list-and-dict-types
2018-11-04
23:49
merge trunk check-in: 7b85bdfca9 user: dkf tags: poly1305
01:38
Start development of partial redundancy elimination. Complete though base-case of the dataflow solution. check-in: 534d2b9f68 user: kbk tags: kbk-pre
2018-11-01
22:04
Allow IMPURE values to builtin mathfuncs check-in: dfc7885448 user: kbk tags: trunk
2018-10-31
11:05
use [my Warn] correctly check-in: b99007d3a3 user: dkf tags: trunk
Changes

Changes to demos/perftest/tester.tcl.

1954
1955
1956
1957
1958
1959
1960




1961
1962
1963
1964
1965
1966
1967
....
2277
2278
2279
2280
2281
2282
2283


2284
2285
2286
2287
2288
2289
2290
....
2446
2447
2448
2449
2450
2451
2452

2453
2454
2455
2456
2457
2458
2459
	    lappend results "n= $n\tCollisions= $col \t\t\tCurrent n_min= $n_min_col\tCurrent min_col=$min_col"
	}
	return [llength $results]
    }

}




 
# A simple helper that is not compiled, but rather just shortens code below

proc cleanopt {script} {
    variable cleanopt
    set code [uplevel 1 [list catch $script cleanopt(msg) cleanopt(opt)]]
    set msg $cleanopt(msg)
................................................................................
    upvartest2::test2
    upvartest2::test3
    upvartest2::test4

    {hash::H9fast ultraantidisestablishmentarianistically}
    {hash::H9mid ultraantidisestablishmentarianistically}
    {hash::H9slow ultraantidisestablishmentarianistically}


}
set demos'slow' {
    {flightawarebench::test 5 5 2}
    {llength [hash::main]}
}
 
#########################################################################
................................................................................
    upvar0
    upvar0a
    upvartest0::*
    upvartest1::*
    upvartest2::*
    flightawarebench::*
    hash::*

}
set toCompile'slow' {
    parseBuiltinsTxt::main
}
 
#############################################################################
#






>
>
>
>







 







>
>







 







>







1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
....
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
....
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
	    lappend results "n= $n\tCollisions= $col \t\t\tCurrent n_min= $n_min_col\tCurrent min_col=$min_col"
	}
	return [llength $results]
    }

}

proc wideimpure {x} {
    expr {wide($x)}
}
 
# A simple helper that is not compiled, but rather just shortens code below

proc cleanopt {script} {
    variable cleanopt
    set code [uplevel 1 [list catch $script cleanopt(msg) cleanopt(opt)]]
    set msg $cleanopt(msg)
................................................................................
    upvartest2::test2
    upvartest2::test3
    upvartest2::test4

    {hash::H9fast ultraantidisestablishmentarianistically}
    {hash::H9mid ultraantidisestablishmentarianistically}
    {hash::H9slow ultraantidisestablishmentarianistically}

    {wideimpure 3.0}
}
set demos'slow' {
    {flightawarebench::test 5 5 2}
    {llength [hash::main]}
}
 
#########################################################################
................................................................................
    upvar0
    upvar0a
    upvartest0::*
    upvartest1::*
    upvartest2::*
    flightawarebench::*
    hash::*
    wideimpure
}
set toCompile'slow' {
    parseBuiltinsTxt::main
}
 
#############################################################################
#

Changes to quadcode/translate.tcl.

1727
1728
1729
1730
1731
1732
1733
1734

1735
1736
1737
1738
1739
1740
1741
....
1771
1772
1773
1774
1775
1776
1777


1778
1779
1780
1781
1782
1783
1784
1785
# generate-function-param-check --
#
#	Generates a check to make sure that a value conforms with a function's
#	requirement for its parameter type. Do not call from anywhere but
#	bytecode-to-quads!
#
# Parameters:
#	q - The quadruple that will consume the value

#
# Results:
#	None.
#
# Side effects:
#	Inserts a parameter type checking sequence.
#
................................................................................
	# 2
	my quads [list initParamTypeException $i] {temp @exception} \
	    $val $functionName
	# 3
	my quads extractFail {temp @exception} {temp @exception}
	# 4
	my generate-jump $target


	# 5
	# (next instruction)
	
    }
}

# quads --
#






|
>







 







>
>
|







1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
....
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
# generate-function-param-check --
#
#	Generates a check to make sure that a value conforms with a function's
#	requirement for its parameter type. Do not call from anywhere but
#	bytecode-to-quads!
#
# Parameters:
#	q - A list comprising the function name and arguments expressed as
#           quadcode values.
#
# Results:
#	None.
#
# Side effects:
#	Inserts a parameter type checking sequence.
#
................................................................................
	# 2
	my quads [list initParamTypeException $i] {temp @exception} \
	    $val $functionName
	# 3
	my quads extractFail {temp @exception} {temp @exception}
	# 4
	my generate-jump $target
	# 5 - ok:
        my quads [list purifyParam $i] $val $val $functionName
	# 6
	# (next instruction)
	
    }
}

# quads --
#

Changes to quadcode/typecheck.tcl.

269
270
271
272
273
274
275

276
277
278
279
280
281
282
283

284
285
286
287
288
289














290
291
292
293
294
295
296
			lset bbcontent $b $j \
			    [list initException $result $msgLit $exn \
				 {literal 1} {literal 0}]
			incr j
		    } else {
			my removeUse $src $b
			my replaceUses $result Nothing

		    }

		}

		"instanceOfParamType" {
		    lassign $q op result src fref
		    set t [my determineFunctionParamType $op $fref]
		    if {$t != $quadcode::dataType::STRING} {

			set op [list "instanceOf" $t [nameOfType $t]]
			lset bbcontent $b $j [list $op $result $src]
			incr j
		    } else {
			my removeUse $src $b
			my replaceUses $result {literal 1}














		    }
		}

		default {
		    lset bbcontent $b $j $q
		    incr j
		}






>








>






>
>
>
>
>
>
>
>
>
>
>
>
>
>







269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
			lset bbcontent $b $j \
			    [list initException $result $msgLit $exn \
				 {literal 1} {literal 0}]
			incr j
		    } else {
			my removeUse $src $b
			my replaceUses $result Nothing
			# delete the quad
		    }

		}

		"instanceOfParamType" {
		    lassign $q op result src fref
		    set t [my determineFunctionParamType $op $fref]
		    if {$t != $quadcode::dataType::STRING} {
			set t [expr {$t | $quadcode::dataType::IMPURE}]
			set op [list "instanceOf" $t [nameOfType $t]]
			lset bbcontent $b $j [list $op $result $src]
			incr j
		    } else {
			my removeUse $src $b
			my replaceUses $result {literal 1}
			# delete the quad
		    }
		}

		"purifyParam" {
		    lassign $q op result src fref
		    set t [my determineFunctionParamType $op $fref]
		    if {$t != $quadcode::dataType::STRING} {
			lset bbcontent $b $j [list purify $result $src]
			incr j
		    } else {
			my removeUse $src $b
			my replaceUses $result $src
			# delete the quad
		    }
		}

		default {
		    lset bbcontent $b $j $q
		    incr j
		}

Changes to quadcode/types.tcl.

579
580
581
582
583
584
585





586
587
588
589
590
591
592
	}
	copy {
	    return [typeOfOperand $types [lindex $q 2]]
	}
	purify {
	    return [expr {[typeOfOperand $types [lindex $q 2]] & ~$IMPURE}]
	}





	unset {
	    return $NEXIST
	}
	setReturnCode {
	    return $FAIL
	}
	initException {






>
>
>
>
>







579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
	}
	copy {
	    return [typeOfOperand $types [lindex $q 2]]
	}
	purify {
	    return [expr {[typeOfOperand $types [lindex $q 2]] & ~$IMPURE}]
	}
	purifyParam {
	    # Will be replaced with 'purify' when type is known, but must
	    # be at most a subset of the type of the source operand
	    return [typeOfOperand $types [lindex $q 2]]
	}
	unset {
	    return $NEXIST
	}
	setReturnCode {
	    return $FAIL
	}
	initException {

Changes to quadcodes.txt.

243
244
245
246
247
248
249








250
251
252
253
   1 or 0 according to the result.
{{instanceOfParamType N} TGT SRC CMD}
   Sets TGT to 1 or 0 depending on whether the type of SRC is appropriate
   as parameter #N to the command CMD
{{initParamTypeException N} TGT SRC CMD}
   Sets TGT to a FAIL value indicating that SRC is inappropriate for parameter
   #N to the command CMD.









For these operations, the data types that must be implemented are INT32,
INT, ENTIER, DOUBLE; the same four data types unioned with EMPTY; and the
complements of these eight types, so there are sixteen variants in all. 






>
>
>
>
>
>
>
>




243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
   1 or 0 according to the result.
{{instanceOfParamType N} TGT SRC CMD}
   Sets TGT to 1 or 0 depending on whether the type of SRC is appropriate
   as parameter #N to the command CMD
{{initParamTypeException N} TGT SRC CMD}
   Sets TGT to a FAIL value indicating that SRC is inappropriate for parameter
   #N to the command CMD.
{purify TGT SRC}
   Sets TGT to SRC, with any IMPURE indication removed
{{purifyParam N} TGT SRC FUNC}
   Sets TGT to SRC, with any IMPURE indication removed, if FUNC is a built-in
   math function requiring a pure value as argument #N.
   Otherwise, simply sets TGT to SRC. This operation is
   replaced with 'purify' or removed during optimization. It is there to
   purify the operands of built-in mathfuncs.

For these operations, the data types that must be implemented are INT32,
INT, ENTIER, DOUBLE; the same four data types unioned with EMPTY; and the
complements of these eight types, so there are sixteen variants in all.