MVP #1
6
Makefile
6
Makefile
@ -15,8 +15,8 @@ WASM2C := $(WABT_DIR)/bin/wasm2c
|
|||||||
# %.exe: %.c
|
# %.exe: %.c
|
||||||
# cc $^ -o $@ -I $(WABT_DIR)/wasm2c
|
# cc $^ -o $@ -I $(WABT_DIR)/wasm2c
|
||||||
|
|
||||||
server: venv/.done
|
examples: venv/.done $(subst .py,.wasm,$(wildcard examples/*.py))
|
||||||
venv/bin/python -m http.server
|
venv/bin/python3 -m http.server --directory examples
|
||||||
|
|
||||||
test: venv/.done
|
test: venv/.done
|
||||||
WAT2WASM=$(WAT2WASM) venv/bin/pytest tests $(TEST_FLAGS)
|
WAT2WASM=$(WAT2WASM) venv/bin/pytest tests $(TEST_FLAGS)
|
||||||
@ -34,3 +34,5 @@ venv/.done: requirements.txt
|
|||||||
touch $@
|
touch $@
|
||||||
|
|
||||||
.SECONDARY: # Keep intermediate files
|
.SECONDARY: # Keep intermediate files
|
||||||
|
|
||||||
|
.PHONY: examples
|
||||||
|
|||||||
34
examples/fib.html
Normal file
34
examples/fib.html
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Examples - Fibonacci</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Fibonacci</h1>
|
||||||
|
|
||||||
|
<a href="fib.py">Source</a> - <a href="fib.wat">WebAssembly</a>
|
||||||
|
|
||||||
|
<div style="white-space: pre;" id="results"></div>
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
let importObject = {};
|
||||||
|
|
||||||
|
let results = document.getElementById('results');
|
||||||
|
|
||||||
|
WebAssembly.instantiateStreaming(fetch('fib.wasm'), importObject)
|
||||||
|
.then(fib => {
|
||||||
|
// 93: 7540113804746346429
|
||||||
|
// i64: 9223372036854775807
|
||||||
|
// 94: 19740274219868223167
|
||||||
|
for(let i = BigInt(1); i < 93; ++i) {
|
||||||
|
let span = document.createElement('span');
|
||||||
|
span.innerHTML = 'fib(' + i + ') = ' + fib.instance.exports.fib(i);
|
||||||
|
results.appendChild(span);
|
||||||
|
let br = document.createElement('br');
|
||||||
|
results.appendChild(br);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -1,10 +1,11 @@
|
|||||||
def helper(n: i32, a: i32, b: i32) -> i32:
|
def helper(n: i64, a: i64, b: i64) -> i64:
|
||||||
if n < 1:
|
if n < 1:
|
||||||
return a + b
|
return a + b
|
||||||
|
|
||||||
return helper(n - 1, a + b, a)
|
return helper(n - 1, a + b, a)
|
||||||
|
|
||||||
def fib(n: i32) -> i32:
|
@exported
|
||||||
|
def fib(n: i64) -> i64:
|
||||||
if n == 0:
|
if n == 0:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@ -14,5 +15,5 @@ def fib(n: i32) -> i32:
|
|||||||
return helper(n - 1, 0, 1)
|
return helper(n - 1, 0, 1)
|
||||||
|
|
||||||
@exported
|
@exported
|
||||||
def testEntry() -> i32:
|
def testEntry() -> i64:
|
||||||
return fib(40)
|
return fib(40)
|
||||||
|
|||||||
11
examples/index.html
Normal file
11
examples/index.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Examples</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Examples</h1>
|
||||||
|
<ul>
|
||||||
|
<li><a href="fib.html">Fibonacci</a></li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -43,6 +43,13 @@ I32_OPERATOR_MAP = { # TODO: Introduce UInt32 type
|
|||||||
'>=': 'ge_s',
|
'>=': 'ge_s',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
I64_OPERATOR_MAP = { # TODO: Introduce UInt32 type
|
||||||
|
'<': 'lt_s',
|
||||||
|
'>': 'gt_s',
|
||||||
|
'<=': 'le_s',
|
||||||
|
'>=': 'ge_s',
|
||||||
|
}
|
||||||
|
|
||||||
def expression(inp: ourlang.Expression) -> Statements:
|
def expression(inp: ourlang.Expression) -> Statements:
|
||||||
if isinstance(inp, ourlang.ConstantInt32):
|
if isinstance(inp, ourlang.ConstantInt32):
|
||||||
yield wasm.Statement('i32.const', str(inp.value))
|
yield wasm.Statement('i32.const', str(inp.value))
|
||||||
@ -79,6 +86,9 @@ def expression(inp: ourlang.Expression) -> Statements:
|
|||||||
if operator := OPERATOR_MAP.get(inp.operator, None):
|
if operator := OPERATOR_MAP.get(inp.operator, None):
|
||||||
yield wasm.Statement(f'i64.{operator}')
|
yield wasm.Statement(f'i64.{operator}')
|
||||||
return
|
return
|
||||||
|
if operator := I64_OPERATOR_MAP.get(inp.operator, None):
|
||||||
|
yield wasm.Statement(f'i64.{operator}')
|
||||||
|
return
|
||||||
if isinstance(inp.type, ourlang.OurTypeFloat32):
|
if isinstance(inp.type, ourlang.OurTypeFloat32):
|
||||||
if operator := OPERATOR_MAP.get(inp.operator, None):
|
if operator := OPERATOR_MAP.get(inp.operator, None):
|
||||||
yield wasm.Statement(f'f32.{operator}')
|
yield wasm.Statement(f'f32.{operator}')
|
||||||
|
|||||||
@ -216,7 +216,12 @@ class Function:
|
|||||||
"""
|
"""
|
||||||
Generates the text version
|
Generates the text version
|
||||||
"""
|
"""
|
||||||
header = ('(export "{}")' if self.exported else '${}').format(self.name)
|
header = f'${self.name}' # Name for internal use
|
||||||
|
|
||||||
|
if self.exported:
|
||||||
|
# Name for external use
|
||||||
|
# TODO: Consider: Make exported('export_name') work
|
||||||
|
header += f' (export "{self.name}")'
|
||||||
|
|
||||||
for nam, typ in self.params:
|
for nam, typ in self.params:
|
||||||
header += f' (param ${nam} {typ.to_wasm()})'
|
header += f' (param ${nam} {typ.to_wasm()})'
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user