1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
use core:io;
use core:lang;
use lang:bs:macro;
/**
* This file looks different from what you would do if you load the package "demo" into "lang.demo".
* The code here essentially emulates Storm's loading behavior. This is not necessary if the package
* is properly loaded. We can't locate it properly here, since that would make it difficult to
* follow the tutorial (there would already be a "lang.demo" package then...).
*/
// This is the contents of the "main.bs" file in the tutorial.
private Str bsCode on Compiler = str{
void main() {
print("f(1, 2) = ${f(1, 2)}");
print("g(4, 2) = ${g(4, 2)}");
print("h(10) = ${h(10)}");
}
Int bsfn(Int x, Int y) {
print("In Basic Storm: ${x}, ${y}");
x + y;
}
};
// This is the contents of the "demo.demo" file in the tutorial.
private Str demoCode on Compiler = str{
f(a, b) = a + b + 1
g(a, b) = f(a, a) * b
h(a) = bsfn(f(a, a), 5)
};
// This main function creates the package reader and loads it manually. As mentioned above, you
// don't need to do this if you locate the "demo" package correctly.
void main() on Compiler {
// Create in-memory files for the code above.
MemoryProtocol protocol;
Url bsFile = protocol.put("test.bs", bsCode);
Url demoFile = protocol.put("demo.demo", demoCode);
print(demoCode);
// Create a temporary package and add it to the name tree as a sub-package to this package
// (named{} is short for the current package).
Package tmpPkg("test");
(named{}).add(tmpPkg);
// Create readers for the file types.
var bsReader = lang:bs:reader([bsFile], tmpPkg);
var demoReader = demo:reader([demoFile], tmpPkg);
// Progressively load the contents:
bsReader.readSyntaxProductions();
demoReader.readSyntaxProductions();
bsReader.readTypes();
demoReader.readTypes();
bsReader.resolveTypes();
demoReader.resolveTypes();
bsReader.readFunctions();
demoReader.readFunctions();
bsReader.resolveFunctions();
demoReader.resolveFunctions();
// Now, we can just find the function "main" in the package!
unless (mainFunction = tmpPkg.find(SimplePart("main"), Scope()) as Function) {
throw InternalError("Failed to find the \"main\" function in the loaded package!");
}
// Get the pointer to the function, cast it to the type we expect, and call it!
unless (ptr = mainFunction.pointer() as fn()->void) {
throw InternalError("The return type of the \"main\" function is not void as expected.");
}
ptr.call();
}
Url put(MemoryProtocol to, Str name, Str contents) {
MemOStream output;
Utf8Output textOut(output);
textOut.write(contents);
textOut.flush();
return to.put(name, output.buffer);
}
|