← Dolaima← Docs indexPerl原文中文

Perl

The "full arithmetic + control flow + function calls" tier: arrays (@a), hashes (%h), subroutines, string handling, loops and recursion all work - enough for something the size of a word-frequency counter.

print takes several arguments at once (printed back to back with no separator), and $var is interpolated inside double-quoted strings.

How to run it on your phone

vml run examples/perl/app/wordcount.pl

Compiling takes a while (one to two minutes for C, a few seconds for scripting languages). Once the program is running, the gamepad is at the bottom of the screen - the D-pad and the four action buttons are all there. Tap the back arrow in the top-right corner to return to the Shell.

What to know before you write

Examples

FileWhat it shows
app/wordcount.plWord frequency counting (split plus a hash tally plus scalar)
hello.plThe smallest program (multi-argument print plus double-quote interpolation)
test/syntax.plA syntax tour: one form used for every feature

Pitfalls we hit on real devices


The rest of this page is taken straight from the VML source (third_party/vml/VMLPrepares/PerlCompiler/): the README covers what this front end supports and how to compile it, and the language reference covers the syntax itself. When upstream changes, regenerating this page brings it up to date.

Language reference

The Perl subset implemented by the PerlCompiler frontend

This document is the implementation contract of the Perl frontend: what syntax and semantics are supported, where the silent traps are, and what is deliberately not supported (and reports a compile-time error instead of pretending). The Chinese version is [PERL_LANGUAGE_SPEC.md](PERL_LANGUAGE_SPEC.md).

Version: v1.0 | Date: 2026-10-13 | Revised by: Shenzhen Tanso Intelligent Technology Co., Ltd.

Specification standard

FieldValue
Target standardPerl 5 subset
Publication year1994
CompletenessSubset (not itemised)
Tests24 passing / 0 failing

Keywords

my our sub if elsif else unless while until for foreach do last next redo return and or not print say use defined undef eq ne lt gt le ge cmp qw

Overview

A subset of Perl 5 is supported, compiled to VML assembly. Variables carry sigils ($ scalar / @ array / % hash; $x, @x and %x are three independent names at the lexical level) and a newline is a statement separator (equivalent to ;). It deliberately does not run the C preprocessor (Perl uses # for line comments, so treating # as a directive marker would turn every comment into an instruction). The frontend has no runtime type tags: it picks between the integer, float and string channels using what can be decided at compile time (parameters read out of @_ and the return values of unknown library functions are of unknown type — see §8). Unimplemented builtins produce a compile-time error; there is no fallback that "quietly runs as 0".

Supported language features

The features this frontend accepts are organised by the sections below; each one states what is accepted and what it means:

See the sections below for details.

0. Principles

1. Lexical

FormNotes
Comments# to end of line
Numbersdecimal integer, 0x… hex, fractional (1.5). Integers are 32-bit (extra bits truncated)
Single-quotedonly \\ and \' are escapes; everything else is literal
Double-quoted\n \t \r \0 \\ \" \$ \@; $name / ${name} interpolate; @name does not (see §5)
Identifiersletters / digits / _ / CJK
Sigils$ scalar, @ array, % hash. A % followed by an identifier is a sigil, otherwise it is modulo
$#alast index of array a (length − 1)
Newlineis a statement separator (equivalent to ;), but suppressed when the previous token is an operator/comma/open bracket, so multi-line expressions still work

Keywords: my our sub if elsif else unless while until for foreach do last next redo return and or not print say use defined undef eq ne lt gt le ge cmp qw.

2. Variables and declarations

3. Expressions and operators

4. Statements and control flow

5. Strings

6. Arrays and hashes

7. Subroutines and use

sub add { my ($x, $y) = @_; return $x + $y; }   # or sub add($x, $y) { … }
print add(3, 4);

8. Compile-time type inference (why it sometimes "guesses wrong")

There are no runtime type tags. The frontend picks the integer / float / string channel from what is statically known:

9. Deliberately unsupported (most report a compile-time error)

FeatureStatus
sort / reverse / each / ucfirst / lcfirst / rindexcompile-time error "not implemented"
References \, deref, anonymous array/hashunsupported
Regex =~, s///, tr///unsupported
Packages / package / objects / blessunsupported
local / state / package semantics of ourunsupported (our is my)
substr as an lvalue, wantarray, context (scalar vs list)unsupported
File handles / open / <> / printf to a handleunsupported (use shared libs / UI tools)
qw()supported (splits into a string list)
64-bit integersunsupported (32-bit)
Float printing formatuses the shared runtime's print_double, fixed 6 decimals (3.4 may show as 3.399999 — that is the shared dtoa's rounding, not a frontend arithmetic error)

10. Criteria

scripts/vml-perl-probe/run.sh runs bugs/vml_perl_bugs/t*.pl and compares stdout byte for byte. It goes through the real channel, vmlcli <case> --lang perl (registry -> assemble -> link -> run), and deliberately does not bypass the registry (that path carries its own link set and would hide a missing language module set). Measured (with the wiring plus GenLib -m -l perl): 24 pass / 0 fail.

Red-ability has been tested twice:

Compiler README

Perl frontend compiler (PerlCompiler)

Compiles a subset of Perl to VML assembly. It is the 23rd frontend under third_party/vml/VMLPrepares/, built like the others: Lexer / Parser / ASTNode / CodeGenerator / PerlPlugin, deriving from CompilerBase and plugged into the host through CompilerPluginExBase.

What the language covers, and what it deliberately does not, is in [PERL_LANGUAGE_SPEC.en.md](PERL_LANGUAGE_SPEC.en.md). The exact wiring steps (host registration / GenLib / packaging) are in [INTEGRATION.md](INTEGRATION.md).

Positioning

It sits in the "full arithmetic + control flow + function calls" tier — you can write ordinary scripts (arrays / hashes / subroutines / string handling / loops / recursion), not just a "hello world that compiles". Examples/perl/app/wordcount.pl (word frequency counting) is the scale it targets.

Quick start

# 1) build the frontend itself (during development it is also a CLI)
dotnet build third_party/vml/VMLPrepares/PerlCompiler -c Release

# 2) compile a .pl into a **self-contained runnable** VML assembly
dotnet third_party/vml/VMLPrepares/PerlCompiler/bin/Release/net10.0/PerlCompiler.dll \
       examples/perl/hello.pl -o /tmp/hello.vml

# 3) run it
dotnet scripts/vmlcli/bin/Release/net10.0/vmlcli.dll /tmp/hello.vml \
       --vml-home third_party/vml --timeout 5

Once wired into the host (see INTEGRATION.md) you can just do vml run examples/perl/hello.pl.

Probe suite
scripts/vml-perl-probe/run.sh              # all
scripts/vml-perl-probe/run.sh t07 t10      # by prefix

Cases live in bugs/vml_perl_bugs/t*.pl and go through the real channel, vmlcli <case> --lang perl (registry -> assemble -> link -> run); measured 24 pass / 0 fail.

Wire it up first (see INTEGRATION.md): (1) register perl into vmlcli's registry per items 1/5/7; (2) run GenLib -m -l perl to generate Lib/perl/*.vml. Without either one the suite either exits 2 loudly (no perl in the registry) or lets the cases go red (missing language module set -> bare-name .linked resolves into another language). The suite deliberately does not bypass the registry: that path carries its own link set and would hide a missing-module defect in the real channel.

Files

FileRole
TokenType.cs / Token.csToken model
Lexer.csLexer (# comments, three sigils, single/double quoted strings, newline as a statement separator)
InterpolationParser.cs$var interpolation and escapes inside double-quoted strings
ASTNode.csAST nodes
Parser.csParser (with paren-less list operators, postfix if/unless, ternary, ++/--)
CodeGenerator.csCode generation: core + statements (slots / control flow / subs / print)
CodeGenerator.Expressions.csExpressions, type inference, builtin dispatch
PerlCompiler.csStatic entry point (read file + use declarations + link stdlib)
PerlPlugin.csPlugin adapter (derives CompilerPluginExBase)
Program.csDevelopment CLI

Runtime and libraries:

PathRole
Lib/perl/perlrt.cLanguage-specific runtime source (dynamic arrays @a / hashes %h / string helpers, pl_ prefix)
Lib/perl/perlrt.vmlThe compiled module (produced by vmlcli --rebuild-lib)
Lib/perl/builtin.vmlStandard library list (a .linked list the compiler reads automatically)
Lib/perl/vml_ui.plDeclaration file for the UI library (constants + function names, for use vml_ui;)

Design notes (where it differs from other frontends)

Known limitations

See the "not supported / intentionally simplified" section of PERL_LANGUAGE_SPEC.en.md. In short: sort / reverse / each / ucfirst / lcfirst / rindex are not implemented and report a compile-time error (no silent fallback); @array does not interpolate inside double quotes; no references / packages / regex / objects; integers are 32-bit.

License

Same as the rest of the repository (VML has forked from upstream, see third_party/vml/FORK.md).