#!/bin/perl -w # Written by David Stewart (last updated 4/21/2005) # Assembler for Simulated Toy Machine # Please save this file as "assem.pl" %translate = ( LOA => [0,2], STO => [1,2], CPR => [2,2], LOI => [3,2], STI => [4,2], ADD => [5,3], SUB => [6,3], MUL => [7,3], DIV => [8,4], INC => [9,1], DCR => [10,1], GTR => [11,3], JMP => [12,1], IFZ => [13,2], JMI => [14,1], TRP => [15,0], ); $const_count = 0; $lineNum = 0; $buffer = ""; $file = shift; open(IN, "<$file"); while($line = ) { chomp $line; if($line =~ m/^(\w{3}) *(.*)$/) { $op = $1; $args = $2; $continue = 0; if(exists($translate{$op})) { if($op eq "JMP") { $string = sprintf "0%x", $translate{$op}[0]; } # JMP has an unused arguement. . . else { $string = sprintf "%x", $translate{$op}[0]; } @tokens = split(/ /, $args); for($i=0;$i<$translate{$op}[1];$i++) { if($tokens[$i] =~ /^R(\d+)/i) { $string = sprintf("%x%s", $1, $string); } else { $string = "<$tokens[$i]>$string"; $constants{$tokens[$i]}[0] = $const_count++; } } @arguments = splice @tokens, 0, $translate{$op}[1]; $comment = join " ", @tokens; $comment =~ s/^\s*//; $args = join " ", @arguments; $lineString = sprintf "%4x", $lineNum; $string = pack "a2 a15 a6 a4 a20", "0x", $string, $lineString, $op, $args; $string =~ tr/[a-f]/[A-F]/; print "$op => $string\n"; $buffer .= join "", $string, $comment, "\n"; $lineNum++; } else{ $continue = 1; } } else { $continue = 1; } if($continue && $line =~ /^\s*([A-Z]+)\s*$/) { # line is a place label (ie a jump destination) $hexLine = sprintf("%x", $lineNum); if($constants{$1}) { $constants{$1}[1] = $hexLine; } else { $constants{$1}[0] = $const_count++; $constants{$1}[1] = $hexLine; } $buffer = join "", $buffer, " $1\n"; } else { $buffer = join "", $buffer, $line, "\n" if $continue; } } close IN; foreach $const (keys %constants) { if(!defined($constants{$const}[1])) { print "Constant found.\n"; while(1) { print "What integer would you like to assign \"$const\"? "; $input = ; if($input =~ /(\d+)/) { $hexLine = sprintf("%x", $lineNum++); $constants{$const}[1] = $hexLine; $line = pack "a19 a4 a*", $1, $hexLine, $const; $line =~ tr/[a-f]/[A-F]/; $buffer .= "$line\n"; last; } else { print "Input not an integer!\n"; } } } $pad = " " x (length($const) - length($constants{$const}[1]) + 2); $buffer =~ s/<$const>(\w*)/$constants{$const}[1]\1$pad/g; } print "$file\n"; $file =~ s/\..*$//; print "$file\n"; open(OUT, ">$file.stm"); print OUT $buffer; close OUT;