Just one small point that @200_success probably left out so I can say something too:
when matching something against $_
, for example in if ($_ =~ /[0-9]+/) { ... }
,
you can simply omit the $_
:
if (/[0-9]+/) {
# ...
}
It's "the default input and pattern-searching space". Read more about the $_
variable in man perlvar
or on perldoc.perl.org.
The main loop in generate_assembly
rewritten to use this (+ a hashmap for the operators):
my %ops = (
'+' => "pop ebx\npop eax\nadd eax,ebx\npush eax\n",
'-' => "pop ebx\npop eax\nsub eax,ebx\npush eax\n",
'/' => "mov edx,0\npop ecx\npop eax\ndiv ecx\npush eax\n",
'*' => "mov edx,0\npop ecx\npop eax\nmul ecx\npush eax\n",
'.' => "push message\ncall printf\nadd esp, 8\n",
);
foreach (@tokens) {
say "<$_>";
if (/[0-9]+/) {
$assembly .= "push $_\n";
} else {
$assembly .= $ops{$_};
}
}
This made me notice one more point: if I add garbage in the input file like this:
256 2 garbage /
The tokenizer will wipe out "garbage" without a warning. This could hide some bugs. I think it would be better to use a more sophisticated parser that can detect syntax errors.
In other words: the language is underspecified. (Thanks @200_success@200_success!)