/Develop/Projects/Vcc/

k1.spdns.de / Develop / Projects / Vcc /

Kio's Virtual Instruction Compiler.

intro | invocation | preprocessor | types | functions | operators | instructions  

compiler | memory  

Compiler

The compiler converts the tokenized words from the preprocessor into an intermediate code for the assembler.

Input Data:
TODO
Output Data:
TODO

Opcodes

The compiler generates an array of opcodes. Actual opcodes are a subclass of class Opcode:

  • LabelOpcode
  • JpOpcode
  • AsmOpcode
  • VarOpcode
  • IvalOpcode
  • CallProcOpcode
  • ProcPtrOpcode
  • CallProcPtrOpcode
  • SwitchOpcode
  • ExtConstOpcode
  • AsmSourceOpcode
  • ForAllEndOpcode
  • The base class has an interface as follows. It provides querrying the actual opcode class and conversion into human readable text. The explicit opcode class tests are for convenience only and do not cover all possible subclasses.

    class Opcode
    {
    opcode_id Oid () const;
    bool Isa (opcode_id o) const;
    bool IsaIval () const;
    bool IsaAsmOpcode() const;
    bool IsaLabel () const;
    bool IsaVar () const;
    cstr ToString () const; // e.g.: "call foo ( int, cstr -- str )"
    };

    LabelOpcode

    class LabelOpcode : public Opcode
    {
    uint Label() const;
    };

    The LabelOpcode defines a label at the current code position. The assembler should not generate any code, but store the label in a manner which allows him to resolve references to this label. Labels are simple uint numbers unique and starting at 0 for each compiled file.

    AsmOpcode

    class AsmOpcode : public Opcode
    {
    cType* RType () const;
    cType* ArgType (uint idx) const;
    idf_id Idf () const;
    cstr Name () const;
    }

    The AsmOpcode is the most often generated opcode. It stores a virtual assembler opcode with information about up to 2 arguments and a return type.

    Member function Idf() returns an idf_id, which is a global enumeration for all known identifiers. These are enumerated in file 'idf_id.h' and all start with a lowercase 't'. The enumeration allows for fast selection of a code generation handler with a switch statement in the assember.

    Member function Name() returns the readable name for this assembler opcode. This allows to print the name of an assembler opcode if the switch statement falls through all cases.

    A full list of opcodes should be listed somewhere. TODO

    Opcode Overloading

    class cType is the base type for all target data types throughout the compiler. The assembler must extract the types and check them in order to generate the correct code. There are many opcodes which have identical names and just work on different data types.

    case tPPPEEK:
    {
    cType a1 = opcodes[i].ArgType(0);
    cType rt = opcodes[i].RType();
     
    assert(rt->RefSubtype() == a1);
    static ForthAsmop o[] = { ForthPPPEEKi16, ForthPPPEEKi32, ForthPPPEEKfloat };
    zcode.append( o[(rt->RealSize()-1)/2] );
    continue;
    }

    The above is an example for a '++peek' funktion handler. The assertion might be omitted (but was helpful for debugging the compiler). Then a static array of 3 opcode variants is defined and the actual one picked based on the data type's size and appended to the generated code in the array named 'zcode'.

    JpOpcode

    The JpOpcode is based on the AsmOpcode and adds a label for a jump target:

    class JpOpcode : public AsmOpcode
    {
    uint Label() const;
    };

    Possible opcodes (idf_id's) are:

  • tJP
  • tJP_Z
  • tJP_NZ
  • tAND0
  • tOR1
  • tFORALLITEMS
  • tFORRANGE
  • tDUP2_FORRANGE
  • tGROW_FORRANGE
  • VarOpcode

    class VarOpcode : public Opcode
    {
    Variable* Var () const;
    style_id Context () const;
    cType* VType () const;
    uint Stack () const;
    };

    The VarOpcode is generated to access a local or global variable. The kind of access can be either oid_vref, oid_vget or oid_vset, which can be tested with Opcode::Oid() or Opcode::Isa(opcode_id). Getters or setters for allocted data types must also just get/set the pointer and do no memory allocation/deallocation.

  • oid_vref: Push a pointer to the variable
  • oid_vget: Peek and push the contents of the variable
  • oid_vset: Pop and store a value into the variable
  • Function Context() returns an enumeration which indicated the kind of variable:

  • global: global variable
  • member: member data in a struct
  • local: local variable of a function
  • context1: local variable of a surrounding function
  • context2: ...
  • Function Stack() returns the size of data currently on the vstack (argument stack). This can be used to access local variables via the vstack pointer instead of a local variables base pointer, saving one address register.

    IvalOpcode

    TODO

    CallProcOpcode

    TODO

    ProcPtrOpcode

    TODO

    CallProcPtrOpcode

    TODO

    SwitchOpcode

    TODO

    ExtConstOpcode

    TODO

    AsmSourceOpcode

    TODO

    ForAllEndOpcode

    TODO

    Archive

    Name Letzte Änderung Länge 
    lib-Z80-Rop/ 2020-11-30 15:50 21 
    lib-Z80-Vss/ 2017-11-12 09:55 452 
    lib/ 2019-10-30 17:02
    Libraries/ 2019-10-30 17:11
    OSX-Qt40/ 2019-10-30 17:02
    OSX/ 2020-09-05 12:54
    Source/ 2019-10-30 17:02 11 
    Tests/ 2019-10-30 17:02
    LICENSE 2019-10-30 17:25 1323 
    README.md 2019-10-30 17:25 288 
    TODO.txt 2020-10-18 12:42 340 
    macspin.gif

    powered by vipsi - your friendly VIP Script Interpreter

    Valid HTML Valid CSS