Integrate the C compiler to the simulator

Signed-off-by: Junjie Mao <junjie.mao@enight.me>
This commit is contained in:
Junjie Mao 2015-12-01 13:57:50 +08:00
parent 40b4c1949b
commit 03ffdfec35
18 changed files with 133 additions and 353 deletions

5
.gitignore vendored
View File

@ -5,3 +5,8 @@ ASMSimulator.iml
*~
*.new
*.old
*.txt
cucu-cc
*.o
*.pyc

71
Simserver.py Executable file
View File

@ -0,0 +1,71 @@
#!/usr/bin/env python
import BaseHTTPServer
import urlparse
import os
import unittest
import json
from cucu.cucu import CucuVM
class WebRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_POST(self):
payload = json.loads(self.rfile.read(int(self.headers['content-length'])))
source = payload["source"].split('\n')
real_source = ''
for line in source:
if not line.startswith(';'):
real_source += line + '\n'
c = CucuVM(real_source)
parsed_path = urlparse.urlparse(self.path)
message_parts = [
'CLIENT VALUES:',
'client_address=%s (%s)' % (self.client_address,
self.address_string()),
'command=%s' % self.command,
'path=%s' % self.path,
'real path=%s' % parsed_path.path,
'query=%s' % parsed_path.query,
'request_version=%s' % self.request_version,
'',
'SERVER VALUES:',
'server_version=%s' % self.server_version,
'sys_version=%s' % self.sys_version,
'protocol_version=%s' % self.protocol_version,
'',
'HEADERS RECEIVED:',
]
for name, value in sorted(self.headers.items()):
message_parts.append('%s=%s' % (name, value.rstrip()))
message_parts.append('')
message = '\n'.join(message_parts)
self.send_response(200)
self.end_headers()
self.wfile.write(c.code)
def do_GET(self):
parsed_path = urlparse.urlparse(self.path)
pa = self.path;
self.send_response(200)
self.end_headers()
if(pa[0:17] == "/examples/scandir"):
info = os.getcwd();
arr = sorted(os.listdir(info+"/examples"));
results = []
for fn in arr:
if not fn.endswith('.txt'):
continue
f = open('examples/' + fn, 'r')
line = f.readlines()[0].strip()
if 'HIDE' in line:
continue
results.append('"%s|%s"' % (fn, line[2:]))
text = '[%s]' % ','.join(results)
self.wfile.write(text);
else:
if pa == "/":
pa = "/index.html"
input = open(pa[1:],"r");
self.wfile.write(input.read());
input.close()
server = BaseHTTPServer.HTTPServer(('0.0.0.0',8082), WebRequestHandler)
server.serve_forever()

18
cucu/Makefile Normal file
View File

@ -0,0 +1,18 @@
#CFLAGS := -Wall -W -std=c89
all: cucu-cc
cucu-cc: cucu.o
$(CC) -o $@ $<
cucu.o: cucu.c gen.c
$(CC) -c $< -DGEN=\"gen.c\" -o $@
install: cucu-cc
cp cucu-cc ..
clean:
rm -f cucu
rm -f *.o
.PHONY: all

0
cucu/__init__.py Normal file
View File

View File

@ -6,7 +6,7 @@ import time
# Interpret VM instruction
#
class CucuVM:
CUCU_PATH='cucu-dummy.exe'
CUCU_PATH='./cucu-cc'
def __init__(self, src, debug=False):
self.A = 0
self.B = 0
@ -128,5 +128,3 @@ class CucuVM:
print("A:%04x B:%04x PC:%x SP:%x" % (self.A, self.B, self.PC, self.SP))
print("Mem:", self.mem)
print()

View File

@ -1,24 +0,0 @@
#CFLAGS := -Wall -W -std=c89
all: cucu-dummy
test: cucu-dummy-test cucu-x86-test
cucu-dummy: cucu-dummy.o
cucu-dummy.o: cucu.c gen-dummy/gen.c
$(CC) -c $< -DGEN=\"gen-dummy/gen.c\" -o $@
cucu-dummy-test: cucu-dummy
python gen-dummy/test.py
cucu-x86: cucu-x86.o
cucu-x86.o: cucu.c gen-x86/gen.c
$(CC) -c $< -DGEN=\"gen-x86/gen.c\" -o $@
cucu-x86-test: cucu-x86
sh gen-x86/test.sh
clean:
rm -f cucu-dummy
rm -f cucu-x86
rm -f *.o
.PHONY: all

View File

@ -1,70 +0,0 @@
import BaseHTTPServer
import urlparse
import os
import unittest
from cucu import CucuVM
class WebRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_POST(self):
#print(self.client_address)
code = self.rfile.read(int(self.headers['content-length']))[2:]
code = code.replace('+',' ')
code = code.replace('%0A','\r\n')
code = code.replace('%3B',';')
code = code.replace('%2B','+')
code = code.replace('%3D','=')
code = code.replace('%7B','{')
code = code.replace('%7D','}')
print code
c = CucuVM(code)
parsed_path = urlparse.urlparse(self.path)
message_parts = [
'CLIENT VALUES:',
'client_address=%s (%s)' % (self.client_address,
self.address_string()),
'command=%s' % self.command,
'path=%s' % self.path,
'real path=%s' % parsed_path.path,
'query=%s' % parsed_path.query,
'request_version=%s' % self.request_version,
'',
'SERVER VALUES:',
'server_version=%s' % self.server_version,
'sys_version=%s' % self.sys_version,
'protocol_version=%s' % self.protocol_version,
'',
'HEADERS RECEIVED:',
]
for name, value in sorted(self.headers.items()):
message_parts.append('%s=%s' % (name, value.rstrip()))
message_parts.append('')
message = '\r\n'.join(message_parts)
self.send_response(200)
self.end_headers()
self.wfile.write(c.code)
def do_GET(self):
parsed_path = urlparse.urlparse(self.path)
print(self.path);
pa = self.path;
self.send_response(200)
self.end_headers()
#print pa;
#print pa[0:2]
#print pa[0:2] == "/ex"
if(pa[0:17] == "/examples/scandir"):
print("!!!!!!!!!!!!!!!!!");
info = os.getcwd();
arr = os.listdir(info+"\examples");
#for i in arr:
# arr = arr + "|1\r\n";
text = '["21-addition.txt|2.1 c = a + b\\r\\n","31-time-sharing-2-processes.txt|3.1 Time-sharing Between Two Processes\\r\\n","51-insertion-sort.txt|5.1 Insertion Sort\\r\\n","52-binary-search.txt|5.2 Binary Search\\r\\n","61-call-by-value.txt|6.1 Passing Parameters by Value\\r\\n","62-call-by-reference.txt|6.2 Passing Parameters by Reference\\r\\n"]';
self.wfile.write(text);
else:
print(">>>>>>>>>>>>>>>>>");
input = open(self.path[1:],"r");
self.wfile.write(input.read());
input.close()
server = BaseHTTPServer.HTTPServer(('127.0.0.1',8080), WebRequestHandler)
server.serve_forever()

Binary file not shown.

View File

@ -1,191 +0,0 @@
<!DOCTYPE html>
<html ng-app="ASMSimulator">
<head>
<title>Simple 8-bit V8-CPU in Javascript</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/style.css">
</head>
<body ng-controller="Ctrl">
<nav class="navbar navbar-inverse" role="navigation" style="background-color:#428BCA;border:0px;border-radius:0px;">
<div class="container">
<div class="navbar-header">
<div class="btn-group">
<button type="button" class="btn btn-success navbar-btn" ng-click="run()" ng-hide="isRunning"><span class="glyphicon glyphicon-play"></span> Run</button>
<button type="button" class="btn btn-default navbar-btn" ng-click="stop()" ng-show="isRunning"><span class="glyphicon glyphicon-stop"></span> Stop</button>
<button type="button" class="btn btn-default navbar-btn" ng-click="executeStep()" ng-disabled="isRunning"><span class="glyphicon glyphicon-forward"></span> Step</button>
</div>
<button type="button" class="btn btn-default navbar-btn" ng-click="reset()">Reset</button>
</div>
<div class="navbar-header navbar-right">
<a class="navbar-brand" style="color:#FFFFFF">Simple 8-bit V8-CPU</a>
</div>
</div>
</nav>
<div class="container">
<div class="alert alert-danger" ng-hide="error === ''">{{ error }}</div>
<div class="row">
<div class="col-lg-7 col-md-6">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">Code <small>(<a href="./instruction-set.html" target="_blank" style="color: #337AB7">Instruction Set</a>)</small></h4>
</div>
<button type="button" class="btn btn-default" ng-click="compile()">Compile</button>
<script>
function postcode()
{
var ta = document.getElementById("sourceCode");
$.post('/',{"1":ta.value},function(response){
ta.value = response;
});
}
</script>
<button type="button" class="btn btn-default" ng-click="assemble()">Assemble</button>
<button type="button" class="btn btn-default" ng-click="upload()">Upload</button>
Examples:
<select ng-model="example" ng-options="item.id as item.desc for item in examples" ng-change="showExample(example)" ng-init="initExamples()"></select>
<!-- <select id="examples" ng-change="showExample(x)" ng-model="x"> -->
<!-- <option value="haha">haha</option> -->
<!-- <option value="hoho">hoho</option> -->
<!-- </select> -->
<form role="form">
<textarea id="sourceCode"
class="form-control source-code"
style="margin-bottom:5px;"
rows="30"
tab-support
select-line
ng-model="code"></textarea>
</form>
</div>
</div>
<div class="clearfix visible-xs visible-sm"></div>
<div class="col-lg-5 col-md-6">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">Printer</h4>
</div>
<div class="panel-body source-code">{{ printer.data }}</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">CPU & Memory</h4>
</div>
<div class="panel-body">
<p class="text-muted">General Registers</p>
<table class="table table-condensed table-striped">
<thead>
<tr>
<th style="text-align:center">0</th>
<th style="text-align:center">1</th>
<th style="text-align:center">2</th>
<th style="text-align:center">3</th>
<th style="text-align:center">4</th>
<th style="text-align:center">5</th>
<th style="text-align:center">6</th>
<th style="text-align:center">7</th>
<th style="text-align:center">8</th>
<th style="text-align:center">9</th>
<th style="text-align:center">A</th>
<th style="text-align:center">B</th>
<th style="text-align:center">C</th>
<th style="text-align:center">D</th>
<th style="text-align:center">E</th>
<th style="text-align:center">F</th>
</tr>
</thead>
<tbody>
<tr style="text-align:center;" class="source-code">
<td><div style="margin:auto;" ng-class="displayA && 'marker marker-a'"><small>{{ cpu.gpr[0] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" ng-class="displayB && 'marker marker-b'"><small>{{ cpu.gpr[1] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" ng-class="displayC && 'marker marker-c'"><small>{{ cpu.gpr[2] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" ng-class="displayD && 'marker marker-d'"><small>{{ cpu.gpr[3] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" ng-class="displayD && 'marker marker-d'"><small>{{ cpu.gpr[4] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" ng-class="displayD && 'marker marker-d'"><small>{{ cpu.gpr[5] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" ng-class="displayD && 'marker marker-d'"><small>{{ cpu.gpr[6] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" ng-class="displayD && 'marker marker-d'"><small>{{ cpu.gpr[7] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" ng-class="displayD && 'marker marker-d'"><small>{{ cpu.gpr[8] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" ng-class="displayD && 'marker marker-d'"><small>{{ cpu.gpr[9] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" ng-class="displayD && 'marker marker-d'"><small>{{ cpu.gpr[10] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" ng-class="displayD && 'marker marker-d'"><small>{{ cpu.gpr[11] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" ng-class="displayD && 'marker marker-d'"><small>{{ cpu.gpr[12] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" ng-class="displayD && 'marker marker-d'"><small>{{ cpu.gpr[13] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" ng-class="displayD && 'marker marker-d'"><small>{{ cpu.gpr[14] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" ng-class="displayD && 'marker marker-d'"><small>{{ cpu.gpr[15] | number:displayHex }}</small></div></td>
</tr>
</tbody>
</table>
<p class="text-muted">Other Registers</p>
<table class="table table-condensed table-striped">
<tbody>
<tr>
<td style="text-align:left">Program counter <font color="E81F1F">{{ cpu.status }}</font> </td>
<td style="text-align:center;" class="source-code"><div style="margin:auto;" class="marker marker-ip"><small>{{ cpu.ip | number:displayHex }}</small></div></td>
</tr>
<tr>
<td style="text-align:left">Instruction register</td>
<td style="text-align:center;" class="source-code"><div style="margin:auto;"><small>{{ cpu.ir | number:displayHex }}</small></div></td>
</tr>
<tr>
<td style="text-align:left">Timer countdown</td>
<td style="text-align:center;" class="source-code"><div style="margin:auto;"><small>{{ cpu.countdown | number:displayHex }}</small></div></td>
</tr>
</tbody>
</table>
<p class="text-muted">RAM</p>
<div style="width:29em;" class="source-code">
<div class="memory-block"
ng-repeat="m in memory.data track by $index"
ng-class="getMemoryCellCss($index)">
<div ng-class="getMemoryInnerCellCss($index)" ng-switch="isInstruction($index)">
<small ng-switch-default>{{ m | number:displayHex }}</small>
<a ng-switch-when="true" ng-click="jumpToLine($index)">
<small>{{ m | number:displayHex }}</small>
</a>
</div>
</div>
</div>
<p style="margin-top:5px;">
<small>
<span>Clock speed:</span>
<select ng-model="speed" ng-options="item.speed as item.desc for item in speeds"></select>
<span style="margin-left:5px;">Instructions:</span>
<a ng-click="displayInstr = true" ng-hide="displayInstr">Show</a>
<a ng-click="displayInstr = false" ng-show="displayInstr">Hide</a>
</small>
</p>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">Labels</h4>
</div>
<div class="panel-body source-code">
<table class="table table-condensed table-striped codelabels">
<tr>
<th>Name</th>
<th>Address</th>
<th>Value</th>
</tr>
<tr ng-repeat="(name, value) in labels" class="codelabel">
<td class="codelabel-name">{{ name }}</td>
<td class="codelabel-line"><a ng-click="jumpToLine(value)">{{ value | number:displayHex }}</a></td>
<td class="codelabel-value">{{ memory.data[value] | number:displayHex }}</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<hr style="margin-top:10px;margin-bottom:10px;"/>
<p><small>by Yuanchun Shi, Yu Chen, Junjie Mao, Yukang Yan (2015) | MIT License | <a href="https://www.github.com/chyyuu/v8-cpu" target="_blank">Source Code</a></small></p>
<p><small>by Marco Schweighauser (2015) | MIT License | <a href="https://www.mschweighauser.com/make-your-own-assembler-simulator-in-javascript-part1/" target="_blank">Blog</a></small></p>
</div>
<script src="node_modules/angular/angular.min.js"></script>
<script src="assets/asmsimulator.min.js"></script>
<script src="/jquery-1.11.3.min.js">
</script>
</body>
</html>

Binary file not shown.

View File

@ -1,5 +0,0 @@
cucu.py, cucu-dummy.exe, Simserver.pys三个文件应放置在与index.html同一目录下
启动server: Python Simserver.py
http://localhost:8080/index.html 为目前的页面url
在textarea内编辑c 代码点击complie返回v8代码点击assemble后可以run,简单写了两个testcase是test1.txt和test2.txt。

View File

@ -1,6 +0,0 @@
int main()
{
int i = 3;
int j = 5;
i = i + j;
}

View File

@ -1,8 +0,0 @@
int main()
{
int i = 5;
while(i != 10)
{
i = i + 1;
}
}

View File

@ -1,9 +0,0 @@
int main()
{
int i = 3;
int j = 5;
if(i != 5)
{
j = 6;
}
}

View File

@ -28,14 +28,27 @@
<div class="col-lg-7 col-md-6">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">Code
<small>(<a href="http://enight.me/files/csao/v8spec.pdf" target="_blank" style="color: #337AB7">Architecture Specification</a>&nbsp;&nbsp;<a href="./instruction-set.html" target="_blank" style="color: #337AB7">Instruction Set</a>)
</small></h4>
<h4 class="panel-title">Code <small>(<a href="./instruction-set.html" target="_blank" style="color: #337AB7">Instruction Set</a>) (<a href="http://enight.me/files/csao/v8spec.pdf" target="_blank" style="color: #337AB7">Specification</a>)</small></h4>
</div>
<button type="button" class="btn btn-default" ng-click="assemble()">Assembly</button>
<button type="button" class="btn btn-default" ng-click="upload()">Machine Code</button>
<button type="button" class="btn btn-default" ng-click="compile()">Compile</button>
<script>
function postcode()
{
var ta = document.getElementById("sourceCode");
$.post('/',{"1":ta.value},function(response){
ta.value = response;
});
}
</script>
<button type="button" class="btn btn-default" ng-click="assemble()">Assemble</button>
<button type="button" class="btn btn-default" ng-click="upload()">Upload</button>
Examples:
<select ng-model="example" ng-options="item.id as item.desc for item in examples" ng-change="showExample(example)" ng-init="initExamples()"></select>
<!-- <select id="examples" ng-change="showExample(x)" ng-model="x"> -->
<!-- <option value="haha">haha</option> -->
<!-- <option value="hoho">hoho</option> -->
<!-- </select> -->
<form role="form">
<textarea id="sourceCode"
class="form-control source-code"
@ -46,15 +59,15 @@
ng-model="code"></textarea>
</form>
</div>
</div>
<div class="clearfix visible-xs visible-sm"></div>
<div class="col-lg-5 col-md-6">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">Printer</h4>
</div>
<div class="panel-body source-code">{{ printer.data }}</div>
</div>
</div>
<div class="clearfix visible-xs visible-sm"></div>
<div class="col-lg-5 col-md-6">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">CPU & Memory</h4>
@ -171,5 +184,7 @@
</div>
<script src="node_modules/angular/angular.min.js"></script>
<script src="assets/asmsimulator.min.js"></script>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
</body>
</html>

View File

@ -18,9 +18,7 @@ app.controller('Ctrl', ['$document', '$scope', '$timeout', '$http', 'cpu', 'memo
$scope.example = '';
$scope.examples = [];
$scope.codeFormat = '';
$scope.code = ";; Choose an example above or write your own code here :)\n\n";
$scope.code = ";; Choose an example above or write your own code here :)";
$scope.reset = function () {
cpu.reset();
memory.reset();
@ -31,11 +29,11 @@ app.controller('Ctrl', ['$document', '$scope', '$timeout', '$http', 'cpu', 'memo
};
$scope.executeStep = function () {
try {
if (!$scope.checkPrgrmLoaded()) {
$scope.updateCode();
}
if (!$scope.checkPrgrmLoaded()) {
$scope.assemble();
}
try {
// Execute
var res = cpu.step();
@ -53,13 +51,8 @@ app.controller('Ctrl', ['$document', '$scope', '$timeout', '$http', 'cpu', 'memo
var runner;
$scope.run = function () {
try {
if (!$scope.checkPrgrmLoaded()) {
$scope.updateCode();
}
} catch (e) {
$scope.error = e;
return;
if (!$scope.checkPrgrmLoaded()) {
$scope.assemble();
}
$scope.isRunning = true;
@ -97,20 +90,9 @@ app.controller('Ctrl', ['$document', '$scope', '$timeout', '$http', 'cpu', 'memo
}
};
$scope.updateCode = function () {
if ($scope.codeFormat == 'assembly') {
$scope.assemble();
} else if ($scope.codeFormat == 'raw') {
$scope.upload();
} else {
throw "Please compile/assemble/upload your code.";
}
};
$scope.assemble = function () {
try {
$scope.reset();
$scope.codeFormat = 'assembly';
var assembly = assembler.go($scope.code);
$scope.mapping = assembly.mapping;
@ -140,7 +122,6 @@ app.controller('Ctrl', ['$document', '$scope', '$timeout', '$http', 'cpu', 'memo
$scope.upload = function () {
try {
$scope.reset();
$scope.codeFormat = 'raw';
var binarycode = uploader.go($scope.code);
$scope.mapping = binarycode.mapping;
@ -163,6 +144,11 @@ app.controller('Ctrl', ['$document', '$scope', '$timeout', '$http', 'cpu', 'memo
}
};
$scope.compile = function () {
$http.post('/', {"source": $scope.code}).success(function(response){
$scope.code = response; $scope.assemble();});
};
$scope.initExamples = function() {
var response = $http.get('examples/scandir.php');
response.success(function(data, status, headers, config) {