Example #1
0
 internal static void Init()
 {
     MKL.Lic("Wendicka Project - Instruction.cs", "GNU General Public License 3");
     MKL.Version("Wendicka Project - Instruction.cs", "20.03.09");
     Set("end", new Instruction(0, delegate(Source.Line l) { return(l.Parameters.Length == 0); }));
     Set("call", new Instruction(1, delegate(Source.Line l) {
         //var ret = true;
         var p = l.Parameters;
         if (p.Length == 0)
         {
             WASM_Main.VP("\nNothing to call"); return(false);
         }
         System.Diagnostics.Debug.WriteLine($"Checking call! Total parameters {p.Length}");
         if (p[0].Kind != Source.DataKind.API && p[0].Kind != Source.DataKind.Chunk && p[0].Kind != Source.DataKind.GlobalVar && p[0].Kind != Source.DataKind.LocalVar)
         {
             WASM_Main.Error($"Uncallable call: {p[0].Kind}"); return(false);
         }
         return(true);
     }));
     Set("invoke", new Instruction(2, Get("call").Check));
     Set("defer", new Instruction(3, Get("call").Check));
     Set("resume", new Instruction(4, delegate { throw new Exception("resume after yield not yet implemented"); }));
     Set("return", new Instruction(5));
     Set("yield", new Instruction(6));
 }
Example #2
0
        static internal void Go(string srcfile)
        {
            VP($"Assembling: {srcfile}");
            var   src          = new Source(srcfile);
            var   ofile        = $"{qstr.StripExt(srcfile)}.WBIN";
            var   bo           = QuickStream.WriteFile(ofile); bo.WriteString($"Wendicka Binary {(char)26}", true);
            var   Chunks       = new SortedDictionary <string, Chunk>();
            Chunk CurrentChunk = null;

            try {
                var lastspace = 0;
                foreach (Source.Line L in src.Lines)
                {
                    for (int p = 0; p < lastspace; p++)
                    {
                        WASM_Main.VT(" ");
                    }
                    WASM_Main.VT("\r");
                    var s = $"{L.From_File}:{L.Line_Number}";
                    lastspace = s.Length;
                    WASM_Main.VT($"{s}\r");
                    Debug.WriteLine(s);
                    var instr = Instruction.Get(L.Instruction);
                    if (L.Instruction == "CHUNK")
                    {
                        if (!ValidID(L.ParamString))
                        {
                            throw new Exception($"Illegal chunk name: {L.ParamString}");
                        }
                        var CName = L.ParamString.ToUpper();
                        if (Chunks.ContainsKey(CName))
                        {
                            WASM_Main.VP("");
                            WASM_Main.WARN($"Duplicate chunk name {CName}! Code will be appended to existing chunk! Is that what you wanted?");
                            CurrentChunk = Chunks[CName];
                            Debug.WriteLine($"Appending to Chunk: {CName}");
                        }
                        else
                        {
                            Debug.WriteLine($"Creating Chunk: {CName}");
                            CurrentChunk  = new Chunk();
                            Chunks[CName] = CurrentChunk;
                        }
                    }
                    else if (L.Instruction.Length > 0 && (L.Instruction[0] == ':' || L.Instruction[L.Instruction.Length - 1] == ':'))
                    {
                        var Lab = L.Instruction.Replace(":", "").ToUpper();
                        if (CurrentChunk == null)
                        {
                            throw new Exception("Label requires chunk");
                        }
                        CurrentChunk.Labels[Lab] = CurrentChunk.Length;
                    }
                    else if (instr == null)
                    {
                        throw new Exception($"Unknown instruction! \"{L.Instruction}\"!");
                    }
                    else if (!instr.Check(L))
                    {
                        throw new Exception($"Instruction {L.Instruction} does not provide the parameters wanted, or has otherwise bad input!");
                    }
                    else if (CurrentChunk == null)
                    {
                        throw new Exception("No chunk!");
                    }
                    else
                    {
                        // If all is good, let's do it!
                        Debug.WriteLine($"Writing instruction {L.Instruction}/{Instruction.Get(L.Instruction).insnum}");
                        CurrentChunk.Add((byte)2);
                        CurrentChunk.Add((byte)Instruction.Get(L.Instruction).insnum);
                        foreach (Source.Parameter p in L.Parameters)
                        {
                            switch (p.Kind)
                            {
                            case Source.DataKind.StartChunk:
                            case Source.DataKind.Einde:
                            case Source.DataKind.Instruction:
                                throw new Exception($"Internal error! Illegal instruction parameter! {p.Kind}");

                            case Source.DataKind.Index:
                                CurrentChunk.Add((byte)Source.DataKind.Index);
                                break;

                            case Source.DataKind.Chunk:
                            case Source.DataKind.String:
                            case Source.DataKind.LocalVar:
                            case Source.DataKind.GlobalVar:
                            case Source.DataKind.API:
                                CurrentChunk.Add((byte)p.Kind);
                                CurrentChunk.Add(p.StrValue);
                                break;

                            case Source.DataKind.Label:
                                CurrentChunk.Add((byte)Source.DataKind.Label);
                                CurrentChunk.RequestedLabels[CurrentChunk.Length] = p.StrValue.ToString();
                                Debug.WriteLine($"Label {p.StrValue} requested at offset {CurrentChunk.Length}");
                                CurrentChunk.Add((int)0);
                                break;

                            case Source.DataKind.Reference:
                                throw new Exception("No support for referrence (yet)");

                            case Source.DataKind.IntValue:
                                CurrentChunk.Add((byte)Source.DataKind.IntValue);
                                CurrentChunk.Add(p.intvalue);
                                break;

                            case Source.DataKind.FloatValue:
                                throw new Exception("No support for float yet");

                            case Source.DataKind.Boolean: {
                                var c = p.StrValue.ToString().ToUpper() == "TRUE" || p.StrValue.ToString().ToUpper() == "YES";
                                CurrentChunk.Add((byte)Source.DataKind.Boolean);
                                CurrentChunk.Add((byte)p.intvalue);
                                break;
                            }

                            case Source.DataKind.Null:
                                CurrentChunk.Add((byte)12);
                                break;

                            default:
                                throw new Exception($"Unknown datakind {p.Kind}! Source version conflict? Internal error?");
                            }
                        }
                        CurrentChunk.Add((byte)0);
                        Debug.WriteLine($"Instruction {L.Instruction} ended");
                    }
                }
                for (int p = 0; p < lastspace; p++)
                {
                    WASM_Main.VT(" ");
                }
                WASM_Main.VT("\r");
                VP($"    Saving: {ofile}");
                foreach (string k in Chunks.Keys)
                {
                    var Chnk = Chunks[k];
                    Debug.WriteLine($"Chunk: {k}");
                    Debug.WriteLine("= Configuring Labels");
                    foreach (int ofs in Chnk.RequestedLabels.Keys)
                    {
                        var Lab = Chnk.RequestedLabels[ofs];
                        var o   = BitConverter.GetBytes(Chnk.Labels[Lab]);
                        Debug.WriteLine($"  = {ofs} => {Lab}");
                        if (!BitConverter.IsLittleEndian)
                        {
                            Array.Reverse(o);
                        }
                        for (byte i = 0; i < 4; ++i)
                        {
                            Chnk.buffer[ofs + i] = o[i];
                        }
                    }
                    Debug.WriteLine("= Writing Chunk Buffer");
                    bo.WriteByte((byte)Source.DataKind.StartChunk);
                    bo.WriteByte(1); bo.WriteString(k);
                    bo.WriteByte(2); bo.WriteInt(Chnk.buffer.Length);
                    bo.WriteByte(0); bo.WriteBytes(Chnk.buffer); bo.WriteByte(0);
                }
                bo.WriteString("WBIN", true);
                bo.WriteInt((int)bo.Size + 4);
                bo.WriteString("WBIN", true);
            } catch (Exception e) {
                WASM_Main.VP("\n");
                WASM_Main.Error(e);
            } finally {
                bo.Close();
            }
        }