Compiler/virtual machine interpreter: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) m (Reverted edits by Jwells1213 (talk) to last revision by Chemoelectric) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 153: | Line 153: | ||
; A simple example virtual machine: |
; A simple example virtual machine: |
||
< |
<syntaxhighlight lang="python">def run_vm(data_size) |
||
int stack[data_size + 1000] |
int stack[data_size + 1000] |
||
set stack[0..data_size - 1] to 0 |
set stack[0..data_size - 1] to 0 |
||
Line 190: | Line 190: | ||
elif op == PRTS: print the constant string referred to by stack[-1]; stack.pop() |
elif op == PRTS: print the constant string referred to by stack[-1]; stack.pop() |
||
elif op == PRTI: print stack[-1] as an integer; stack.pop() |
elif op == PRTI: print stack[-1] as an integer; stack.pop() |
||
elif op == HALT: break</ |
elif op == HALT: break</syntaxhighlight> |
||
; Additional examples |
; Additional examples |
||
Line 219: | Line 219: | ||
<syntaxhighlight lang="ada">-- |
|||
<lang Ada>-- |
|||
-- The Rosetta Code Virtual Machine, in Ada. |
-- The Rosetta Code Virtual Machine, in Ada. |
||
-- |
-- |
||
Line 1,153: | Line 1,153: | ||
Set_Exit_Status (status); |
Set_Exit_Status (status); |
||
end VM;</ |
end VM;</syntaxhighlight> |
||
Line 1,169: | Line 1,169: | ||
=={{header|Aime}}== |
=={{header|Aime}}== |
||
<lang>integer n, pc, sp; |
<syntaxhighlight lang="text">integer n, pc, sp; |
||
file f; |
file f; |
||
text s; |
text s; |
||
Line 1,255: | Line 1,255: | ||
isk_greater(code, pc, pc); |
isk_greater(code, pc, pc); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|ALGOL W}}== |
=={{header|ALGOL W}}== |
||
< |
<syntaxhighlight lang="algolw">begin % virtual machine interpreter % |
||
% string literals % |
% string literals % |
||
string(256) array stringValue ( 0 :: 256 ); |
string(256) array stringValue ( 0 :: 256 ); |
||
Line 1,564: | Line 1,564: | ||
end while_not_halted |
end while_not_halted |
||
end |
end |
||
end.</ |
end.</syntaxhighlight> |
||
=={{header|ATS}}== |
=={{header|ATS}}== |
||
Line 1,575: | Line 1,575: | ||
(Without the C optimizer, ATS code can run much, much more slowly. It is worth comparing the Mandelbrot example with and without the optimizer.) |
(Without the C optimizer, ATS code can run much, much more slowly. It is worth comparing the Mandelbrot example with and without the optimizer.) |
||
< |
<syntaxhighlight lang="ats">(* |
||
Usage: vm [INPUTFILE [OUTPUTFILE]] |
Usage: vm [INPUTFILE [OUTPUTFILE]] |
||
If INPUTFILE or OUTPUTFILE is "-" or missing, then standard input |
If INPUTFILE or OUTPUTFILE is "-" or missing, then standard input |
||
Line 3,377: | Line 3,377: | ||
} |
} |
||
(********************************************************************)</ |
(********************************************************************)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,393: | Line 3,393: | ||
=={{header|AWK}}== |
=={{header|AWK}}== |
||
Tested with gawk 4.1.1 and mawk 1.3.4. |
Tested with gawk 4.1.1 and mawk 1.3.4. |
||
<syntaxhighlight lang="awk"> |
|||
<lang AWK> |
|||
function error(msg) { |
function error(msg) { |
||
printf("%s\n", msg) |
printf("%s\n", msg) |
||
Line 3,548: | Line 3,548: | ||
run_vm(data_size) |
run_vm(data_size) |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out|case=count}} |
{{out|case=count}} |
||
<b> |
<b> |
||
Line 3,566: | Line 3,566: | ||
=={{header|C}}== |
=={{header|C}}== |
||
Tested with gcc 4.81 and later, compiles warning free with -Wall -Wextra |
Tested with gcc 4.81 and later, compiles warning free with -Wall -Wextra |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
#include <stdarg.h> |
#include <stdarg.h> |
||
Line 3,832: | Line 3,832: | ||
int data[1000 + data_size]; |
int data[1000 + data_size]; |
||
run_vm(object, data, data_size, string_pool); |
run_vm(object, data, data_size, string_pool); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|COBOL}}== |
=={{header|COBOL}}== |
||
Code by Steve Williams (with changes to work around code highlighting issues). Tested with GnuCOBOL 2.2. |
Code by Steve Williams (with changes to work around code highlighting issues). Tested with GnuCOBOL 2.2. |
||
< |
<syntaxhighlight lang="cobol"> >>SOURCE FORMAT IS FREE |
||
identification division. |
identification division. |
||
*> this code is dedicated to the public domain |
*> this code is dedicated to the public domain |
||
Line 4,258: | Line 4,258: | ||
end program emitword. |
end program emitword. |
||
end program vminterpreter.</ |
end program vminterpreter.</syntaxhighlight> |
||
{{out|case=Count}} |
{{out|case=Count}} |
||
Line 4,282: | Line 4,282: | ||
< |
<syntaxhighlight lang="lisp">#!/bin/sh |
||
#|-*- mode:lisp -*-|# |
#|-*- mode:lisp -*-|# |
||
#| |
#| |
||
Line 5,006: | Line 5,006: | ||
(uiop:quit 0))) |
(uiop:quit 0))) |
||
;;; vim: set ft=lisp lisp:</ |
;;; vim: set ft=lisp lisp:</syntaxhighlight> |
||
Line 5,032: | Line 5,032: | ||
<syntaxhighlight lang="d">// |
|||
<lang D>// |
|||
// The Rosetta Code Virtual Machine in D. |
// The Rosetta Code Virtual Machine in D. |
||
// |
// |
||
Line 5,938: | Line 5,938: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
Line 5,957: | Line 5,957: | ||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
Tested with Gforth 0.7.3 |
Tested with Gforth 0.7.3 |
||
< |
<syntaxhighlight lang="forth">CREATE BUF 0 , \ single-character look-ahead buffer |
||
: PEEK BUF @ 0= IF KEY BUF ! THEN BUF @ ; |
: PEEK BUF @ 0= IF KEY BUF ! THEN BUF @ ; |
||
: GETC PEEK 0 BUF ! ; |
: GETC PEEK 0 BUF ! ; |
||
Line 6,039: | Line 6,039: | ||
: RUN BYTECODE @ A ! |
: RUN BYTECODE @ A ! |
||
BEGIN C@A+ CELLS OPS + @ EXECUTE AGAIN ; |
BEGIN C@A+ CELLS OPS + @ EXECUTE AGAIN ; |
||
>HEADER >BYTECODE RUN</ |
>HEADER >BYTECODE RUN</syntaxhighlight> |
||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
{{works with|gfortran|11.2.1}} |
{{works with|gfortran|11.2.1}} |
||
Fortran 2008/2018 code with some limited use of the C preprocessor. If you are on a platform with case-sensitive filenames, and call the source file vm.F90, then gfortran will know to use the C preprocessor. |
Fortran 2008/2018 code with some limited use of the C preprocessor. If you are on a platform with case-sensitive filenames, and call the source file vm.F90, then gfortran will know to use the C preprocessor. |
||
< |
<syntaxhighlight lang="fortran">module compiler_type_kinds |
||
use, intrinsic :: iso_fortran_env, only: int32 |
use, intrinsic :: iso_fortran_env, only: int32 |
||
use, intrinsic :: iso_fortran_env, only: int64 |
use, intrinsic :: iso_fortran_env, only: int64 |
||
Line 7,577: | Line 7,577: | ||
end subroutine print_usage |
end subroutine print_usage |
||
end program vm</ |
end program vm</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 7,593: | Line 7,593: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 7,895: | Line 7,895: | ||
scanner = bufio.NewScanner(codeGen) |
scanner = bufio.NewScanner(codeGen) |
||
runVM(loadCode()) |
runVM(loadCode()) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 7,913: | Line 7,913: | ||
=={{header|Icon}}== |
=={{header|Icon}}== |
||
{{trans|ObjectIcon}} |
{{trans|ObjectIcon}} |
||
< |
<syntaxhighlight lang="icon"># -*- Icon -*- |
||
# |
# |
||
# The Rosetta Code virtual machine in Icon. Migrated from the |
# The Rosetta Code virtual machine in Icon. Migrated from the |
||
Line 8,287: | Line 8,287: | ||
write(&errout, "Bad opcode.") |
write(&errout, "Bad opcode.") |
||
exit(1) |
exit(1) |
||
end</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 8,303: | Line 8,303: | ||
=={{header|J}}== |
=={{header|J}}== |
||
Implementation: |
Implementation: |
||
< |
<syntaxhighlight lang="j">(opcodes)=: opcodes=: ;:{{)n |
||
fetch store push add sub mul div mod lt gt le ge |
fetch store push add sub mul div mod lt gt le ge |
||
eq ne and or neg not jmp jz prtc prts prti halt |
eq ne and or neg not jmp jz prtc prts prti halt |
||
Line 8,378: | Line 8,378: | ||
pc=: pc+k |
pc=: pc+k |
||
end. |
end. |
||
}}</ |
}}</syntaxhighlight> |
||
Task example: |
Task example: |
||
< |
<syntaxhighlight lang="j">count=:{{)n |
||
count = 1; |
count = 1; |
||
while (count < 10) { |
while (count < 10) { |
||
Line 8,399: | Line 8,399: | ||
count is: 8 |
count is: 8 |
||
count is: 9 |
count is: 9 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
< |
<syntaxhighlight lang="julia">mutable struct VM32 |
||
code::Vector{UInt8} |
code::Vector{UInt8} |
||
stack::Vector{Int32} |
stack::Vector{Int32} |
||
Line 8,505: | Line 8,505: | ||
const vm = assemble(iob) |
const vm = assemble(iob) |
||
runvm(vm) |
runvm(vm) |
||
</ |
</syntaxhighlight>{{output}}<pre> |
||
count is: 1 |
count is: 1 |
||
count is: 2 |
count is: 2 |
||
Line 8,519: | Line 8,519: | ||
=={{header|M2000 Interpreter}}== |
=={{header|M2000 Interpreter}}== |
||
===Using Select Case=== |
===Using Select Case=== |
||
<syntaxhighlight lang="m2000 interpreter"> |
|||
<lang M2000 Interpreter> |
|||
Module Virtual_Machine_Interpreter (a$){ |
Module Virtual_Machine_Interpreter (a$){ |
||
\\ function to extract string, replacing escape codes. |
\\ function to extract string, replacing escape codes. |
||
Line 8,692: | Line 8,692: | ||
65 halt |
65 halt |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
===Using Lambda functions=== |
===Using Lambda functions=== |
||
Line 8,698: | Line 8,698: | ||
A call local to function pass the current scope to function, so it's like a call to subroutine, but faster. |
A call local to function pass the current scope to function, so it's like a call to subroutine, but faster. |
||
<syntaxhighlight lang="m2000 interpreter"> |
|||
<lang M2000 Interpreter> |
|||
Module Virtual_Machine_Interpreter (a$){ |
Module Virtual_Machine_Interpreter (a$){ |
||
\\ function to extract string, replacing escape codes. |
\\ function to extract string, replacing escape codes. |
||
Line 8,847: | Line 8,847: | ||
65 halt |
65 halt |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Mercury}}== |
=={{header|Mercury}}== |
||
Line 8,860: | Line 8,860: | ||
< |
<syntaxhighlight lang="mercury">%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
||
%%% |
%%% |
||
%%% The Rosetta Code Virtual Machine, in Mercury. |
%%% The Rosetta Code Virtual Machine, in Mercury. |
||
Line 9,751: | Line 9,751: | ||
%%% prolog-indent-width: 2 |
%%% prolog-indent-width: 2 |
||
%%% end: |
%%% end: |
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%</ |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%</syntaxhighlight> |
||
Line 9,773: | Line 9,773: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
< |
<syntaxhighlight lang="nim">import os, parseutils, strutils, strscans, strformat |
||
type |
type |
||
Line 10,093: | Line 10,093: | ||
vm.load(code) |
vm.load(code) |
||
vm.run()</ |
vm.run()</syntaxhighlight> |
||
All tests passed. |
All tests passed. |
||
=={{header|ObjectIcon}}== |
=={{header|ObjectIcon}}== |
||
< |
<syntaxhighlight lang="objecticon"># -*- ObjectIcon -*- |
||
# |
# |
||
# The Rosetta Code virtual machine in Object Icon. |
# The Rosetta Code virtual machine in Object Icon. |
||
Line 10,505: | Line 10,505: | ||
exit(1) |
exit(1) |
||
end |
end |
||
end</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 10,521: | Line 10,521: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
Tested with perl v5.26.1 |
Tested with perl v5.26.1 |
||
< |
<syntaxhighlight lang="perl">#!/usr/bin/perl |
||
# http://www.rosettacode.org/wiki/Compiler/virtual_machine_interpreter |
# http://www.rosettacode.org/wiki/Compiler/virtual_machine_interpreter |
||
Line 10,570: | Line 10,570: | ||
} |
} |
||
$ops[vec($binary, $pc++, 8)][1]->() while 1; # run it</ |
$ops[vec($binary, $pc++, 8)][1]->() while 1; # run it</syntaxhighlight> |
||
Passes all tests. |
Passes all tests. |
||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
Reusing cgen.e from the [[Compiler/code_generator#Phix|Code Generator task]] |
Reusing cgen.e from the [[Compiler/code_generator#Phix|Code Generator task]] |
||
<!--< |
<!--<syntaxhighlight lang="phix">(notonline)--> |
||
<span style="color: #000080;font-style:italic;">-- |
<span style="color: #000080;font-style:italic;">-- |
||
-- demo\rosetta\Compiler\vm.exw |
-- demo\rosetta\Compiler\vm.exw |
||
Line 10,615: | Line 10,615: | ||
<span style="color: #000080;font-style:italic;">--main(command_line())</span> |
<span style="color: #000080;font-style:italic;">--main(command_line())</span> |
||
<span style="color: #000000;">main</span><span style="color: #0000FF;">({</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"count.c"</span><span style="color: #0000FF;">})</span> |
<span style="color: #000000;">main</span><span style="color: #0000FF;">({</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"count.c"</span><span style="color: #0000FF;">})</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 10,633: | Line 10,633: | ||
< |
<syntaxhighlight lang="prolog">%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
||
%%% |
%%% |
||
%%% The Rosetta Code Virtual Machine, for GNU Prolog. |
%%% The Rosetta Code Virtual Machine, for GNU Prolog. |
||
Line 10,999: | Line 10,999: | ||
%%% prolog-indent-width: 2 |
%%% prolog-indent-width: 2 |
||
%%% end: |
%%% end: |
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%</ |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%</syntaxhighlight> |
||
Line 11,016: | Line 11,016: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
Tested with Python 2.7 and 3.x |
Tested with Python 2.7 and 3.x |
||
< |
<syntaxhighlight lang="python">from __future__ import print_function |
||
import sys, struct |
import sys, struct |
||
Line 11,183: | Line 11,183: | ||
data_size = load_code() |
data_size = load_code() |
||
run_vm(data_size)</ |
run_vm(data_size)</syntaxhighlight> |
||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
Line 11,194: | Line 11,194: | ||
< |
<syntaxhighlight lang="racket">#lang typed/racket |
||
;;; |
;;; |
||
;;; The Rosetta Code Virtual Machine, in Typed Racket. |
;;; The Rosetta Code Virtual Machine, in Typed Racket. |
||
Line 11,941: | Line 11,941: | ||
(close-output-port outf)) |
(close-output-port outf)) |
||
(exit 0)))))</ |
(exit 0)))))</syntaxhighlight> |
||
Line 11,966: | Line 11,966: | ||
{{trans|Perl}} |
{{trans|Perl}} |
||
<lang |
<syntaxhighlight lang="raku" line>my @CODE = q:to/END/.lines; |
||
Datasize: 3 Strings: 2 |
Datasize: 3 Strings: 2 |
||
"count is: " |
"count is: " |
||
Line 12,043: | Line 12,043: | ||
$pc += $w; |
$pc += $w; |
||
%ops{%n2op{ $opcode }}(); |
%ops{%n2op{ $opcode }}(); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>count is: 1 |
<pre>count is: 1 |
||
Line 12,061: | Line 12,061: | ||
< |
<syntaxhighlight lang="ratfor">###################################################################### |
||
# |
# |
||
# The Rosetta Code code virtual machine in Ratfor 77. |
# The Rosetta Code code virtual machine in Ratfor 77. |
||
Line 13,293: | Line 13,293: | ||
end |
end |
||
######################################################################</ |
######################################################################</syntaxhighlight> |
||
Line 13,330: | Line 13,330: | ||
The following code implements a virtual machine for the output of the [http://rosettacode.org/wiki/Compiler/code_generator#Scala code generator]. |
The following code implements a virtual machine for the output of the [http://rosettacode.org/wiki/Compiler/code_generator#Scala code generator]. |
||
< |
<syntaxhighlight lang="scala"> |
||
package xyz.hyperreal.rosettacodeCompiler |
package xyz.hyperreal.rosettacodeCompiler |
||
Line 13,547: | Line 13,547: | ||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
The above code depends on the function <tt>unescape()</tt> to perform string escape sequence translation. That function is defined in the following separate source file. |
The above code depends on the function <tt>unescape()</tt> to perform string escape sequence translation. That function is defined in the following separate source file. |
||
< |
<syntaxhighlight lang="scala"> |
||
package xyz.hyperreal |
package xyz.hyperreal |
||
Line 13,579: | Line 13,579: | ||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Scheme}}== |
=={{header|Scheme}}== |
||
Line 13,587: | Line 13,587: | ||
All of the "Compiler/Sample programs" are correctly interpreted. |
All of the "Compiler/Sample programs" are correctly interpreted. |
||
< |
<syntaxhighlight lang="scheme"> |
||
(import (scheme base) |
(import (scheme base) |
||
(scheme char) |
(scheme char) |
||
Line 13,750: | Line 13,750: | ||
(run-program data strings code)) |
(run-program data strings code)) |
||
(display "Error: pass a .asm filename\n")) |
(display "Error: pass a .asm filename\n")) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
Line 13,758: | Line 13,758: | ||
{{libheader|Wren-fmt}} |
{{libheader|Wren-fmt}} |
||
{{libheader|Wren-ioutil}} |
{{libheader|Wren-ioutil}} |
||
< |
<syntaxhighlight lang="ecmascript">import "/dynamic" for Enum |
||
import "/crypto" for Bytes |
import "/crypto" for Bytes |
||
import "/fmt" for Conv |
import "/fmt" for Conv |
||
Line 14,024: | Line 14,024: | ||
lines = FileUtil.readLines("codegen.txt") |
lines = FileUtil.readLines("codegen.txt") |
||
lineCount = lines.count |
lineCount = lines.count |
||
runVM.call(loadCode.call())</ |
runVM.call(loadCode.call())</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 14,040: | Line 14,040: | ||
=={{header|Zig}}== |
=={{header|Zig}}== |
||
< |
<syntaxhighlight lang="zig"> |
||
const std = @import("std"); |
const std = @import("std"); |
||
Line 14,363: | Line 14,363: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
File rvm.zkl: |
File rvm.zkl: |
||
< |
<syntaxhighlight lang="zkl">// This is a little endian machine |
||
const WORD_SIZE=4; |
const WORD_SIZE=4; |
||
const{ var _n=-1; var[proxy]N=fcn{ _n+=1 } } // enumerator |
const{ var _n=-1; var[proxy]N=fcn{ _n+=1 } } // enumerator |
||
Line 14,429: | Line 14,429: | ||
code.del(0,sz+2); |
code.del(0,sz+2); |
||
} |
} |
||
run_vm(code,1000);</ |
run_vm(code,1000);</syntaxhighlight> |
||
The binary code file code.bin: |
The binary code file code.bin: |
||
{{out}} |
{{out}} |