*/
List<string> extraCode;
+ /*
+ * 'extraCodeDefer' is for C code that is to be added in the C
+ * output _after_ the data and code blocks.
+ */
+ List<string> extraCodeDefer;
+
/*
* 'dataBlock' is the data block in which constant data bytes
* are accumulated.
StringComparer.Ordinal);
compiling = false;
extraCode = new List<string>();
+ extraCodeDefer = new List<string>();
enableFlowAnalysis = true;
/*
extraCode.Add(ParseCCode());
});
+ /*
+ * postamble
+ * Parses a C code snippet, then adds it to the generated
+ * output after the data and code blocks.
+ */
+ AddNative("postamble", false, SType.BLANK, cpu => {
+ extraCodeDefer.Add(ParseCCode());
+ });
+
/*
* make-CX
* Expects two integers and a string, and makes a
}
CodeElement[] gcode = gcodeList.ToArray();
+ /*
+ * If there are less than 256 words in total (C +
+ * interpreted) then we can use "one-byte code" which is
+ * more compact when the number of words is in the
+ * 128..255 range.
+ */
+ bool oneByteCode;
+ if (slotInterpreted + numInterpreted >= 256) {
+ Console.WriteLine("WARNING: more than 255 words");
+ oneByteCode = false;
+ } else {
+ oneByteCode = true;
+ }
+
/*
* Compute all addresses and offsets. This loops until
* the addresses stabilize.
int[] gcodeLen = new int[gcode.Length];
for (;;) {
for (int i = 0; i < gcode.Length; i ++) {
- gcodeLen[i] = gcode[i].Length;
+ gcodeLen[i] = gcode[i].GetLength(oneByteCode);
}
int off = 0;
for (int i = 0; i < gcode.Length; i ++) {
#define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0)
#define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0)
-static const uint8_t t0_datablock[];
+/* static const unsigned char t0_datablock[]; */
");
/*
BlobWriter bw;
tw.WriteLine();
- tw.Write("static const uint8_t t0_datablock[] = {");
+ tw.Write("static const unsigned char"
+ + " t0_datablock[] = {");
bw = new BlobWriter(tw, 78, 1);
bw.Append((byte)0);
foreach (ConstData cd in blocks.Values) {
tw.WriteLine("};");
tw.WriteLine();
- tw.Write("static const uint8_t t0_codeblock[] = {");
+ tw.Write("static const unsigned char"
+ + " t0_codeblock[] = {");
bw = new BlobWriter(tw, 78, 1);
foreach (CodeElement ce in gcode) {
- ce.Encode(bw);
+ ce.Encode(bw, oneByteCode);
}
tw.WriteLine();
tw.WriteLine("};");
wordSet[ep].Slot);
}
tw.WriteLine();
+ if (oneByteCode) {
+ tw.WriteLine("{0}",
+@"#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++)");
+ } else {
+ tw.WriteLine("{0}",
+@"#define T0_NEXT(t0ipp) t0_parse7E_unsigned(t0ipp)");
+ }
+ tw.WriteLine();
tw.WriteLine("void");
tw.WriteLine("{0}_run(void *t0ctx)", coreRun);
tw.WriteLine("{0}",
#define T0_CO() do { \
goto t0_exit; \
} while (0)
-#define T0_RET() break
+#define T0_RET() goto t0_next
dp = ((t0_context *)t0ctx)->dp;
rp = ((t0_context *)t0ctx)->rp;
ip = ((t0_context *)t0ctx)->ip;
+ goto t0_next;
for (;;) {
uint32_t t0x;
- t0x = t0_parse7E_unsigned(&ip);
+ t0_next:
+ t0x = T0_NEXT(&ip);
if (t0x < T0_INTERPRETED) {
switch (t0x) {
int32_t t0off;
((t0_context *)t0ctx)->rp = rp;
((t0_context *)t0ctx)->ip = ip;
}");
+
+ /*
+ * Add the "postamblr" elements here. These are
+ * elements that may need access to the data
+ * block or code block, so they must occur after
+ * their definition.
+ */
+ foreach (string pp in extraCodeDefer) {
+ tw.WriteLine();
+ tw.WriteLine("{0}", pp);
+ }
}
int codeLen = 0;
foreach (CodeElement ce in gcode) {
- codeLen += ce.Length;
+ codeLen += ce.GetLength(oneByteCode);
}
int dataBlockLen = 0;
foreach (ConstData cd in blocks.Values) {
*/
Console.WriteLine("code length: {0,6} byte(s)", codeLen);
Console.WriteLine("data length: {0,6} byte(s)", dataLen);
- Console.WriteLine("interpreted words: {0}",
- interpretedEntry.Length);
+ Console.WriteLine("total words: {0} (interpreted: {1})",
+ slotInterpreted + numInterpreted, numInterpreted);
}
internal Word Lookup(string name)