Skip to content

Instantly share code, notes, and snippets.

@Mtgxyz
Created December 18, 2014 19:00
Show Gist options
  • Save Mtgxyz/4ff1b889748daafab5a9 to your computer and use it in GitHub Desktop.
Save Mtgxyz/4ff1b889748daafab5a9 to your computer and use it in GitHub Desktop.
Quick, dirty and non-efficient wdc 65816 compiler
<?php
/**qdnec help
Function declaration:
%f <name>; <Function body> %F;
Expression:
0=<main expression>;
Association:
<address (without $ or 0x)>=<main expression>;
Arithmetic Operations:
+ Addition
- Subtraction
* Multiplication
/ Divide
( ) Parthensis
note: operations like 5(a()-$2) are NOT possible
use 5*(a()-$2) instead.
Variables: does not really exists,use addresses instead
Adresses:
Lorom/Hirom addresses with $ as prefix.
function calls:
<name>()
If:
%i<addr1>==<addr2>:<expressions if true>(%e<expressions if false>)%I;
(Expressions, Associations and conditional blocks are expressions)
*/
$look="";
$lcount=0;
$inFunction=false;
$done=false;
function getChar() {
global $look;
$look=fgetc(STDIN);
}
function abort($str) {
die("\nError: $str.");
}
function expected($str) {
abort("$str expected");
}
function newLabel() {
global $lcount;
$lcount++;
return "L".($lcount-1);
}
function postLabel($l){
echo "$l:\n";
}
function isAlpha($c) {
$array=array("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z");
$c=strtolower($c);
for($i=0;$i<count($array);$i++) {
if ($array[$i]==$c)
return true;
}
return false;
}
function isAlNum($c) {
return isAlpha($c) || is_numeric($c);
}
function isWhite($c) {
return $c==" ";
}
function isHexa($c) {
$array=array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f");
$c=strtolower($c);
for($i=0;$i<count($array);$i++) {
if ($array[$i]==$c)
return true;
}
return false;
}
function skipWhite() {
global $look;
while(isWhite($look))
getChar();
}
function match($c) {
global $look;
if($look==$c) {
getChar();
skipWhite();
}
else
expected($c);
}
function getAddress() {
global $look;
if(!isHexa($look)) {
expected("address");
}
$tmp="$";
while(isHexa($look)) {
$tmp.=$look;
getChar();
}
skipWhite();
return $tmp;
}
function getName() {
global $look;
if(!isAlpha($look))
expected("name");
$tmp="";
while(isAlNum($look)) {
$tmp.=$look;
getChar();
}
skipWhite();
return $tmp;
}
function getNum() {
global $look;
$tmp="";
if(!is_numeric($look))
expected("integer");
while(is_numeric($look)) {
$tmp.=$look;
getChar();
}
skipWhite();
return $tmp;
}
function ident() {
global $look;
$name=getName();
if($look=="(") {
match("(");
match(")");
echo "JSR $name\n";
} else
echo "LDA $name\n";
}
function factor() {
global $look;
if($look=="(") {
match("(");
expression();
match(")");
} else if (isAlpha($look))
ident();
else if ($look=="$") {
//Address
match("$");
echo "LDA ".getAddress()."\n";
} else
echo "LDA #".getNum()."\n";
}
function multiply() {
match("*");
factor();
echo "PLX\nSTA $2102\nSTX $2103\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nLDA $4217 ;low 8 bit.\n";
}
function divide() {
match("/");
factor();
echo "STZ $4204\nPLX\nSTX $4205\nSTA $4206\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nLDA $4214\n";
}
function term() {
global $look;
factor();
while(($look=="*")||($look=="/")) {
echo("PHA\n");
switch($look) {
case "*":
multiply();
break;
case "/":
divide();
break;
default:
expected("mulop");
}
}
}
function add() {
global $look;
match("+");
term();
echo "PLX\nSTX $0000\nCLC\nADC $0000\n";
}
function subtract() {
match("-");
global $look;
term();
echo "PLX\nSTX $0000\nSEC\nSBC $0000\nEOR #\$"."FF\nINA\n";
}
function expression() {
global $look;
$addr=getAddress();
match("=");
if(($look=="+")||($look=="-"))
echo "LDA #0\n";
else
term();
while(($look=="+")||($look=="-")) {
echo("PHA\n");
switch($look) {
case "+":
add();
break;
case "-":
subtract();
break;
default:
expected("addop");
}
}
match(";");
echo "STA $addr\n";
}
function condition() {
$addr1=getAddress();
match("=");
match("=");
$addr2=getAddress();
echo "LDA $addr1\nSEC\nSBC $addr2\n";
match(":");
return array($addr1,$addr2);
}
function cmain() {
global $look;
global $inFunction;
global $done;
match("%");
if ($look=="i" && $inFunction) {
match("i");
$l = newLabel();
$addr=condition();
$addr1=$addr[0];
$addr2=$addr[1];
echo "BNE $l\n";
while(isHexa($look)) {
expression();
}
match("%");
if($look=="i") {
cmain();
match("%");
}
postLabel($l);
if($look=="e") {
match("e");
echo "LDA $addr1\nSEC\nSBC $addr2\n";
$l = newLabel();
echo "BEQ $l\n";
while(isHexa($look)) {
expression();
}
match("%");
if($look=="i") {
cmain();
match("%");
}
postLabel($l);
}
match("I");
match(";");
} else if($look=="f") {
match("f");
echo getName().":\n";
match(";");
$inFunction=true;
} else if($look=="F") {
match("F");
match(";");
echo "RTS\n";
$inFunction=false;
} else {
$done=true;
}
}
function init() {
global $look;
global $inFunction;
global $done;
getChar();
while(!$done) {
if($look=="%")
cmain();
else if($inFunction )
while(isHexa($look))
expression();
}
}
init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment