Compiler/virtual machine interpreter: Difference between revisions

Content added Content deleted
m (Reverted edits by Jwells1213 (talk) to last revision by Chemoelectric)
m (syntax highlighting fixup automation)
Line 153: Line 153:
; A simple example virtual machine:
; A simple example virtual machine:


<lang python>def run_vm(data_size)
<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</lang>
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;</lang>
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);
}
}
}</lang>
}</syntaxhighlight>


=={{header|ALGOL W}}==
=={{header|ALGOL W}}==
<lang algolw>begin % virtual machine interpreter %
<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.</lang>
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.)


<lang ats>(*
<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:
}
}


(********************************************************************)</lang>
(********************************************************************)</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
<lang C>#include <stdio.h>
<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);
}</lang>
}</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.


<lang cobol> >>SOURCE FORMAT IS FREE
<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.</lang>
end program vminterpreter.</syntaxhighlight>


{{out|case=Count}}
{{out|case=Count}}
Line 4,282: Line 4,282:




<lang lisp>#!/bin/sh
<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:</lang>
;;; 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;
}</lang>
}</syntaxhighlight>




Line 5,957: Line 5,957:
=={{header|Forth}}==
=={{header|Forth}}==
Tested with Gforth 0.7.3
Tested with Gforth 0.7.3
<lang Forth>CREATE BUF 0 , \ single-character look-ahead buffer
<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</lang>
>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.
<lang fortran>module compiler_type_kinds
<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</lang>
end program vm</syntaxhighlight>


{{out}}
{{out}}
Line 7,593: Line 7,593:
=={{header|Go}}==
=={{header|Go}}==
{{trans|Python}}
{{trans|Python}}
<lang go>package main
<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())
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 7,913: Line 7,913:
=={{header|Icon}}==
=={{header|Icon}}==
{{trans|ObjectIcon}}
{{trans|ObjectIcon}}
<lang icon># -*- Icon -*-
<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</lang>
end</syntaxhighlight>


{{out}}
{{out}}
Line 8,303: Line 8,303:
=={{header|J}}==
=={{header|J}}==
Implementation:
Implementation:
<lang J>(opcodes)=: opcodes=: ;:{{)n
<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.
}}</lang>
}}</syntaxhighlight>


Task example:
Task example:
<lang J>count=:{{)n
<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}}==
<lang julia>mutable struct VM32
<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)
</lang>{{output}}<pre>
</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:




<lang Mercury>%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
<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:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%</lang>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%</syntaxhighlight>




Line 9,773: Line 9,773:
=={{header|Nim}}==
=={{header|Nim}}==


<lang Nim>import os, parseutils, strutils, strscans, strformat
<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()</lang>
vm.run()</syntaxhighlight>


All tests passed.
All tests passed.


=={{header|ObjectIcon}}==
=={{header|ObjectIcon}}==
<lang objecticon># -*- 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</lang>
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
<lang Perl>#!/usr/bin/perl
<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</lang>
$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]]
<!--<lang Phix>(notonline)-->
<!--<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>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
<pre>
<pre>
Line 10,633: Line 10,633:




<lang prolog>%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
<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:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%</lang>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%</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
<lang Python>from __future__ import print_function
<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)</lang>
run_vm(data_size)</syntaxhighlight>


=={{header|Racket}}==
=={{header|Racket}}==
Line 11,194: Line 11,194:




<lang Racket>#lang typed/racket
<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)))))</lang>
(exit 0)))))</syntaxhighlight>




Line 11,966: Line 11,966:


{{trans|Perl}}
{{trans|Perl}}
<lang perl6>my @CODE = q:to/END/.lines;
<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 }}();
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>count is: 1
<pre>count is: 1
Line 12,061: Line 12,061:




<lang ratfor>######################################################################
<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


######################################################################</lang>
######################################################################</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].


<lang scala>
<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.


<lang scala>
<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.


<lang scheme>
<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}}
<lang ecmascript>import "/dynamic" for Enum
<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())</lang>
runVM.call(loadCode.call())</syntaxhighlight>


{{out}}
{{out}}
Line 14,040: Line 14,040:


=={{header|Zig}}==
=={{header|Zig}}==
<lang 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:
<lang zkl>// This is a little endian machine
<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);</lang>
run_vm(code,1000);</syntaxhighlight>
The binary code file code.bin:
The binary code file code.bin:
{{out}}
{{out}}