Skip to content

Instantly share code, notes, and snippets.

@SuperDoxin
Last active December 27, 2015 06:19
Show Gist options
  • Select an option

  • Save SuperDoxin/7280607 to your computer and use it in GitHub Desktop.

Select an option

Save SuperDoxin/7280607 to your computer and use it in GitHub Desktop.
Universal Machine
;temp: F
write A >data
write F >exit
write C >loop ;constant
write D 1 ;constant
write E 0 ;constant
loop: index F E A
out F
add A A D
write G >exit
CMOV G C F
load E G
exit: halt
data: raw 72
raw 101
raw 108
raw 108
raw 111
raw 32
raw 87
raw 111
raw 114
raw 108
raw 100
raw 33
raw 10
raw 0
#!/bin/bash
"""
UASM
Usage:
uasm.py <input> <output>
uasm.py (-h|--help|--version)
Options:
-h --help show this screen
--version show version
"""
from docopt import docopt
import re
import json
import struct
registers=['a','b','c','d','e','f','g','h']
ops=["cmov","index","set","add","mult","div","nand","halt","new","del","out","input","load","write","raw"]
class Pointer(object):
def __init__(self,name=None):
self.name=name
def __repr__(self):
return "J-{}".format(self.name)
class Opcode(object):
def __init__(self,data):
self.pointers=[]
for item in ["reg_a","reg_b","reg_c","value","op","label"]:
try:
setattr(self,item,data.group(item))
except IndexError:
setattr(self,item,None)
pass
if self.op not in ops:
raise SyntaxError("invalid op {!r}".format(self.op))
self.op=ops.index(self.op)
if self.value!=None:
if self.value.startswith(">"):
self.value=Pointer(self.value[1:])
self.pointers.append(self.value)
elif self.value.startswith("0x"):
self.value=int(self.value[2:],16)
else:
self.value=int(self.value)
if self.label!=None:
self.label=self.label[:-1]
#print "LABEL {!r}".format(self.label)
if self.reg_a!=None:
self.reg_a=registers.index(self.reg_a)
if self.reg_b!=None:
self.reg_b=registers.index(self.reg_b)
if self.reg_c!=None:
self.reg_c=registers.index(self.reg_c)
if self.op==12:
self.reg_c=self.reg_b
self.reg_b=self.reg_a
self.reg_a=None
elif self.op==10 or self.op==9:
self.reg_c=self.reg_a
self.reg_a=None
def write(self):
val=self.op<<28
if self.op==13:
try:
val|=self.value&0x1FFFFFF
except TypeError:
val|=self.value.value
val|=self.reg_a<<25
elif self.op==14:
val=self.value
else:
if self.reg_a!=None:
val|=self.reg_a<<6
if self.reg_b!=None:
val|=self.reg_b<<3
if self.reg_c!=None:
val|=self.reg_c
return struct.pack(">L",val)
def __repr__(self):
dct={}
for item in ["reg_a","reg_b","reg_c","value","op","label"]:
v=getattr(self,item)
if v!=None:
dct[item]=v
return "<Opcode {}>".format(dct)
def main(infname,outfname):
outp=[]
labels={}
with open(infname,"r") as fid:
ops=[]
opno=0
for lineno,line in enumerate(fid):
if ";" in line:
line,_,_=line.partition(";")
line=line.lower().strip()
if len(line)==0:
continue
m=None
for i in xrange(1):
#raw data
m=re.match(r"(?P<label>[a-z]+[a-z0-9]*:)?\s*(?P<op>raw)\s+(?P<value>\d+|0x[0-9a-f]+)$",line)
if m:
break
#3 register op
m=re.match(r"(?P<label>[a-z]+[a-z0-9]*:)?\s*(?P<op>[a-z]+)\s+(?P<reg_a>[a-h])\s+(?P<reg_b>[a-h])\s+(?P<reg_c>[a-h])$",line)
if m:
break
#2 register op
m=re.match(r"(?P<label>[a-z]+[a-z0-9]*:)?\s*(?P<op>[a-z]+)\s+(?P<reg_a>[a-h])\s+(?P<reg_b>[a-h])$",line)
if m:
break
#1 reg op
m=re.match(r"(?P<label>[a-z]+[a-z0-9]*:)?\s*(?P<op>[a-z]+)\s+(?P<reg_a>[a-h])$",line)
if m:
break
#0 register op
m=re.match(r"(?P<label>[a-z]+[a-z0-9]*:)?\s*(?P<op>[a-z]+)$",line)
if m:
break
#special op
m=re.match(r"(?P<label>[a-z]+[a-z0-9]*:)?\s*(?P<op>[a-z]+)\s+(?P<reg_a>[a-h])\s+(?P<value>\d+|0x[0-9a-f]+|>[a-z]+[a-z0-9]*)$",line)
if m:
break
if m==None:
raise SystemExit("invalid syntax in line {}".format(lineno+1))
o=Opcode(m)
#print repr(o)
#outp.append(o.write())
o.pos=opno
if o.label!=None:
if o.label in labels:
raise SystemExit("duplicate label {!r}.format(o.label)")
labels[o.label]=o.pos
outp.append(o)
#print repr(o)
opno+=1
for op in outp:
for pointer in op.pointers:
if pointer.name not in labels:
raise SystemExit("undefined label {!r}".format(pointer.name))
pointer.value=labels[pointer.name]
outp=map(lambda x:x.write(),outp)
with open(outfname,"w") as fid:
fid.write(''.join(outp))
print "wrote {} instructions".format(len(outp))
if __name__ == '__main__':
arguments = docopt(__doc__, version='UASM 0.1')
main(arguments["<input>"],arguments["<output>"])
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
FILE *fp;
FILE *wfp;
unsigned int opcount;
unsigned int *array0;
unsigned int pointer=1;
unsigned int op;
unsigned int reg_a;
unsigned int reg_b;
unsigned int reg_c;
unsigned int value;
unsigned int registers[8]={0};
unsigned int data;
unsigned int size;
unsigned char ch;
//printf("argc: %i\n",argc);
if(argc!=3 && argc!=2)
{
printf("Usage:\n um <input> <listing>\n um <input>\n");
}
fp=fopen(argv[1],"r");
if(fp==NULL)
{
perror("Error while opening file.");
return 1;
}
fseek(fp, 0L, SEEK_END);
opcount=ftell(fp)/4;
fseek(fp, 0L, SEEK_SET);
printf("%i ops to read\n",opcount);
array0=(unsigned int*)calloc(opcount+1,sizeof(int));
array0[0]=opcount;
if(argc==3)
wfp=fopen(argv[2],"w");
//fprintf(wfp,"\n")
for(int i=1;i<opcount;i++)
{
array0[i]=(fgetc(fp)<<24)|(fgetc(fp)<<16)|(fgetc(fp)<<8)|(fgetc(fp));
if(argc==3)
{
data=array0[i];
op=data>>28;
if(op==13)
{
reg_a=(data>>25)&0x7;
reg_b=0;
reg_c=0;
value=data&0x1FFFFFF;
}
else
{
reg_c=(data)&0x7;
reg_b=(data>>3)&0x7;
reg_a=(data>>6)&0x7;
value=0;
}
fprintf(wfp,"%8x: ",i);
switch(op)
{
case 0: fprintf(wfp,"CMOV %c==0 ? %c=%c",reg_c+65,reg_a+65,reg_b+65); break;
case 1: fprintf(wfp,"INDEX %c=%c[%c]",reg_a+65,reg_b+65,reg_c+65); break;
case 2: fprintf(wfp,"DIV %c[%c]=%c",reg_a+65,reg_b+65,reg_c+65); break;
case 3: fprintf(wfp,"ADD %c=%c+%c",reg_a+65,reg_b+65,reg_c+65); break;
case 4: fprintf(wfp,"MULT %c=%c*%c",reg_a+65,reg_b+65,reg_c+65); break;
case 5: fprintf(wfp,"DIV %c=%c/%c",reg_a+65,reg_b+65,reg_c+65); break;
case 6: fprintf(wfp,"NAND %c=%cV%c",reg_a+65,reg_b+65,reg_c+65); break;
case 7: fprintf(wfp,"HALT"); break;
case 8: fprintf(wfp,"NEW %c=new[%c]",reg_b+65,reg_c+65); break;
case 9: fprintf(wfp,"DEL %c",reg_c+65); break;
case 10: fprintf(wfp,"OUT %c",reg_c+65); break;
case 11: fprintf(wfp,"INPUT %c=input",reg_c+65); break;
case 12: fprintf(wfp,"LOAD %c\n JMP %c",reg_b+65,reg_c+65); break;
case 13:
if(value>=32 && value<=126)
fprintf(wfp,"WRITE %c=%08x ;%c",reg_a+65,value,value);
else
fprintf(wfp,"WRITE %c=%08x",reg_a+65,value);
break;
default: fprintf(wfp,"DAT %08x",data); break;
}
fprintf(wfp,"\n");
}
}
printf("%i ops read\n---\n",opcount);
if(argc==3)
return 0;
while(1)
{
if(pointer>array0[0])
{
printf("\n=== END OF CODE ===\n");
return 0;
}
data=array0[pointer];
//printf("%u\n",data);
//return 0;
pointer++;
op=data>>28;
if(op==13)
{
reg_a=(data>>25)&0x7;
reg_b=0;
reg_c=0;
value=data&0x1FFFFFF;
}
else
{
reg_c=(data)&0x7;
reg_b=(data>>3)&0x7;
reg_a=(data>>6)&0x7;
value=0;
}
switch(op)
{
case 0:
if(registers[reg_c]!=0)
registers[reg_a]=registers[reg_b];
break;
case 1:
if(registers[reg_b]==0)
registers[reg_a]=array0[registers[reg_c]+1];
else
registers[reg_a]=((int*)registers[reg_b])[registers[reg_c]+1];
break;
case 2:
if(registers[reg_a]==0)
array0[registers[reg_b]+1]=registers[reg_c];
else
((int*)registers[reg_a])[registers[reg_b]+1]=registers[reg_c];
break;
case 3:
registers[reg_a]=registers[reg_b]+registers[reg_c];
break;
case 4:
registers[reg_a]=registers[reg_b]*registers[reg_c];
break;
case 5:
registers[reg_a]=registers[reg_b]/registers[reg_c];
break;
case 6:
registers[reg_a]=~(registers[reg_b]&registers[reg_c]);
break;
case 7:
printf("\n=== HALT ===\nhalted at %08x\n",pointer);
return 0;
case 8:
//printf("[MEM] allocating %08x plates",registers[reg_c]);
size=registers[reg_c];
registers[reg_b]=(unsigned int)calloc(size+1,sizeof(int)); //(int)
//printf(" to %08x\n",registers[reg_b]);
((int*)registers[reg_b])[0]=size;
break;
case 9:
//printf("[MEM] freeing %08x\n",registers[reg_c]);
free((unsigned int*)registers[reg_c]);
break;
case 10:
printf("%c",registers[reg_c]);
break;
case 11:
fflush(stdout);
ch=getchar();
//read(0, &ch, 1);
if(ch=='\n')
registers[reg_c]=255;
else
registers[reg_c]=ch;
break;
case 12:
if(registers[reg_b]!=0)
{
size=((unsigned int*)registers[reg_b])[0];
array0=(unsigned int*)malloc((size+1)*sizeof(int));
memcpy(array0,(unsigned int*)registers[reg_b],(size+1)*sizeof(int));
}
pointer=registers[reg_c]+1;
break;
case 13:
registers[reg_a]=value;
break;
default: printf("Illegal op %i\n",op); return 1;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment