Compile-time calculation: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (syntax highlighting fixup automation)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(17 intermediate revisions by 8 users not shown)
Line 209:
{{output}}
<syntaxhighlight lang="applescript">3628800</syntaxhighlight>
 
=={{header|Arturo}}==
<syntaxhighlight lang="arturo">f10: 1*2*3*4*5*6*7*8*9*10 ; this is evaluated at compile time
 
; the generate bytecode is:
; [ :bytecode
; ================================
; DATA
; ================================
; 0: 3628800 :integer
; 1: f10 :label
 
; ================================
; CODE
; ================================
; push0
; store1
; end
; ]
 
print f10</syntaxhighlight>
 
{{out}}
 
<pre>3628800</pre>
 
=={{header|BASIC}}==
Line 220 ⟶ 245:
 
In both cases, the identifier <code>factorial10</code> is given the value 3628800 without any runtime calculations, although in many (or perhaps most) BASICs the first one is handled similarly to C's <code>#define</code>: if it isn't used elsewhere in the code, it doesn't appear at all in the final executable.
 
=={{header|BASIC256}}==
<syntaxhighlight lang="basic">factorial = 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10
print "10! = "; factorial # 3628800</syntaxhighlight>
 
=={{header|C}}==
Line 442 ⟶ 471:
leave
ret</syntaxhighlight>
 
 
=={{header|C3}}==
C3 has semantic macros that use a different syntax from the regular runtime syntax.
 
<syntaxhighlight lang="c">macro int factorial($n)
{
$if ($n == 0):
return 1;
$else:
return $n * factorial($n - 1);
$endif;
}
 
extern fn void printf(char *fmt, ...);
 
fn void main()
{
int x = factorial(10);
printf("10! = %d\n", x);
}</syntaxhighlight>
 
{{out}}
<pre>10! = 3628800</pre>
 
=={{header|Clojure}}==
Line 575 ⟶ 628:
3628801
</syntaxhighlight>
 
=={{header|EDSAC order code}}==
Under David Wheeler's Initial Orders 2, the effect of compile-time calculation could be achieved on EDSAC by the use of "interludes" in the loading process. Code for an interlude was loaded into store, then loading was paused while the interlude was executed. When finished, the interlude passed control back to initial orders, and normal loading was resumed. Code that was used only by the interlude could then be overwritten. In this way once-only code was not left taking up storage space, which was in short supply on EDSAC.
 
Interludes could be used for calculation or for other purposes. E.g. the library subroutine M3 ran as an interlude; it printed a header on the teleprinter, and then M3 and the header text were overwritten.
 
Code for an interlude should not change locations in the initial orders. Also, if the multiplier register is used, its original value should be restored before exit from the interlude. The interlude in the demo program below is based on a shorter example in Wilkes, Wheeler & Gill, 1951 edn, p. 112.
<syntaxhighlight lang="edsac">
[Demo of calculating a constant in an interlude at load time.
EDSAC program, Initial Orders 2.]
 
[Arrange the storage]
T46K P56F [N parameter: library subroutine P7 to print integer]
T47K P100F [M parameter: main routine]
 
E25K TM GK [M parameter, main routine]
T#Z PF [clear 35-bit value at relative locations
0 & 1, including the middle ("sandwich") bit]
T2#Z PF [same for 2 & 3]
T4#Z PF [same for 4 & 5]
TZ [resume normal loading at relative location 0]
[Storage for interlude, must be at even address]
[0] PD PF [35-bit factorial, initially integer 1]
[2] PD PF [35-bit factor 1..10, initially integer 1]
[4] PF K4096F [to save multiplier register (MR), initially floating point -1]
[6] PD [17-bit integer 1]
[7] P5F [17-bit integer 10 (or number whose factorial is required)]
[8] PF [dump for clearing acc]
[Executable code for interlude; here with acc = 0]
[9] N4#@ [acc := MR, by subtracting (-1 * MR)]
T4#@ [save MR over interlude]
[11] T8@ [start of loop: clear acc]
A2@ [acc := factor]
A6@ [add 1]
T2@ [update factor, clear acc]
H2#@ [MR := factor, extended to 35 bits]
V#@ [times 35-bit product, result in acc]
L1024F L1024F L256F [integer scaling: shift 34 left]
T#@ [update product]
A2@ [acc := factor just used]
S7@ [is it 10 yet?]
G11@ [if not, loop back]
H4#@ [restore MR before exit from interlude]
E25F [pass control back to initial orders]
[At this point the interlude has been loaded but not executed.
The next control combination starts execution.]
E9Z [pass control to relative location 9 above]
PF [value in accumulator when control is passed: here = 0]
[After the interlude, loading resumes here.]
T2Z [resume normal loading at relative location 2,
overwriting the above interlude except the factorial]
[Teleprinter characters]
[2] #F [set figures mode]
[3] @F [carriage return]
[4] &F [line feed]
[Enter here with acc = 0]
[5] O2@ [set teleprinter to figures]
A#@ [acc := factorial, as calculated in the interlude]
TD [pass to print subroutine]
[8] A8@ GN [call print subroutine]
O3@ O4@ [print CR, LF]
O2@ [dummy character to flush teleprinter buffer]
ZF [stop]
 
E25K TN [N parameter]
[Library subroutine P7, prints 35-bit strictly positive integer in 0D.]
[10 characters, right justified, padded left with spaces.]
[Even address; 35 storage locations; working position 4D.]
GKA3FT26@H28#@NDYFLDT4DS27@TFH8@S8@T1FV4DAFG31@SFLDUFOFFFSF
L4FT4DA1FA27@G11@XFT28#ZPFT27ZP1024FP610D@524D!FO30@SFL8FE22@
 
E25K TM GK [M parameter again]
E5Z [define entry point]
PF [acc = 0 on entry]
</syntaxhighlight>
{{out}}
<pre>
3628800
</pre>
 
=={{header|Erlang}}==
Line 704 ⟶ 836:
 
Note: Currently, the mediawiki implementation is corrupting the above display due to a cascading sequence of bad design decisions and mis-interpreted specifications on the part of someone "contributing" to that implementation. To work around this issue, and see the original display, you can currently use either the "Edit" or "View Source" option, depending on whether you are logged in to rosettacode with an account that has edit rights here. (Please don't actually save changes though.) If you are using View Source, you might want to do that in a new tab (so you also stay here with this view) and use your browser's search capability to quickly scroll to this location in the source view.
 
=={{header|Java}}==
<pre>
The Java compiler is able to calculate expressions that contain constant variables
and certain operators during code compilation.
As defined in the Java language specification,
the following operators and expressions may be used for constant expressions:
 
Unary operators: +, -, ~, !
Multiplicative operators: *, /, %
Additive operators: +, –
Shift operators: <<, >>, >>>
Relational operators: <, <=, >, >=
Equality operators: ==, !=
Bitwise and logical operators: &, ^, |
Conditional-and and the conditional-or operator: &&, ||
Ternary conditional operator: ?:
Parenthesized expressions whose contained expression is a constant expression
Simple names that refer to constant variables
</pre>
<syntaxhighlight lang="java">
 
public final class CompileTimeCalculation {
 
public static void main(String[] aArgs) {
System.out.println(tenFactorial);
}
private static int tenFactorial = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1;
 
}
</syntaxhighlight>
{{ out }}
<pre>
3628800
</pre>
 
=={{header|Julia}}==
Line 1,218 ⟶ 1,387:
 
Like Perl 5, we also have a BEGIN block, but it also works to introduce a blockless statement,
the value of which will be stored up to be used inas the surroundingan expression at run time:
 
<syntaxhighlight lang="raku" line> say( BEGIN [*] 2..10);</syntaxhighlight>
 
=={{header|REXX}}==
Line 1,265 ⟶ 1,434:
func factorial nr if nr = 1 return 1 else return nr * factorial(nr-1) ok
</syntaxhighlight>
 
=={{header|Run BASIC}}==
{{works with|Just BASIC}}
{{works with|Liberty BASIC}}
<syntaxhighlight lang="vb">factorial = 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10
print "10! = "; factorial ' 3628800</syntaxhighlight>
 
=={{header|Rust}}==
Line 1,284 ⟶ 1,459:
 
=={{header|Scala}}==
 
Scala 3 supports proper compile time evaluation
 
<syntaxhighlight lang="scala">
transparent inline def factorial(inline n: Int): Int =
inline n match
case 0 => 1
case _ => n * factorial(n - 1)
 
inline val factorial10/*: 3628800*/ = factorial(10)
</syntaxhighlight>
 
Alternative version that works with Scala 2:
 
<syntaxhighlight lang="scala">object Main extends {
val tenFactorial = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2
Line 1,370 ⟶ 1,559:
</syntaxhighlight>
As you can see, that expression was transformed into just a push of the results (and an instruction to mark the end of the bytecode segment).
 
=={{header|TXR}}==
 
In TXR Lisp, the standard <code>macro-time</code> macro evaluates an expression at macro-expansion time, and replaces it by its result, which is then treated as a literal (because the macro inserts `quote` around it, if required).
 
Such a macro is easy to implement in Common Lisp and similar dialects. The [https://www.nongnu.org/txr/txr-manpage.html#N-0131B069 documentation] provides a reference implementation which is easily ported.
 
Example: provide a function <code>buildinfo</code> in the compiled program which returns the build machine name, and time and date of the compilation. A global variable which provides this value could similarly be defined:
 
<syntaxhighlight lang="txrlisp">
(defun buildinfo ()
(macro-time
`Built by @{(uname).nodename} on @(time-string-local (time) "%c")`))
</syntaxhighlight>
 
If we compile and disassemble the function, we see it just contains a canned literal:
 
<pre>
3> (compile 'buildinfo)
#<vm fun: 0 param>
4> (disassemble *3)
data:
0: buildinfo
1: "Built by sun-go on Sat Oct 1 20:01:25 2022"
syms:
code:
0: 8C000005 close t2 0 2 5 0 0 nil
1: 00000002
2: 00000000
3: 00000002
4: 10000401 end d1
5: 10000002 end t2
instruction count:
3
entry point:
4
#<vm fun: 0 param>
</pre>
 
=={{header|Ursala}}==
Line 1,504 ⟶ 1,731:
 
Not that it makes much difference in practice as the compiler which is written in C is so quick (at least with scripts of moderate length and on modern hardware) that the compile and runtime stages are indistinguishable to the user.
<syntaxhighlight lang="ecmascriptwren">var factorial10 = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2
 
System.print(factorial10)</syntaxhighlight>
Line 1,571 ⟶ 1,798:
RET
</pre>
 
=={{header|Yabasic}}==
<syntaxhighlight lang="basic">factorial = 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10
print "10! = ", factorial // 3628800</syntaxhighlight>
 
=={{header|Z80 Assembly}}==
9,479

edits