mirror of https://github.com/OpenMW/openmw.git
added parsing for set statement (only integer values so far); added code generator
parent
5cf3264bd3
commit
fdcd34941b
@ -0,0 +1,120 @@
|
||||
|
||||
#include "generator.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "literals.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
Interpreter::Type_Code segment0 (unsigned int c, unsigned int arg0)
|
||||
{
|
||||
assert (c<64);
|
||||
return (c<<24) | (arg0 & 0xffffff);
|
||||
}
|
||||
|
||||
Interpreter::Type_Code segment1 (unsigned int c, unsigned int arg0, unsigned int arg1)
|
||||
{
|
||||
assert (c<64);
|
||||
return 0x40000000 | (c<<24) | ((arg0 & 0xfff)<<12) | (arg1 & 0xfff);
|
||||
}
|
||||
|
||||
Interpreter::Type_Code segment2 (unsigned int c, unsigned int arg0)
|
||||
{
|
||||
assert (c<1024);
|
||||
return 0x80000000 | (c<<20) | (arg0 & 0xfffff);
|
||||
}
|
||||
|
||||
Interpreter::Type_Code segment3 (unsigned int c, unsigned int arg0)
|
||||
{
|
||||
assert (c<1024);
|
||||
return 0xc0000000 | (c<<20) | (arg0 & 0xffff);
|
||||
}
|
||||
|
||||
Interpreter::Type_Code segment4 (unsigned int c, unsigned int arg0, unsigned int arg1)
|
||||
{
|
||||
assert (c<1024);
|
||||
return 0xc4000000 | (c<<16) | ((arg0 & 0xff)<<8) | (arg1 & 0xff);
|
||||
}
|
||||
|
||||
Interpreter::Type_Code segment5 (unsigned int c)
|
||||
{
|
||||
assert (c<67108864);
|
||||
return 0xc8000000 | c;
|
||||
}
|
||||
|
||||
void opPushInt (Compiler::Generator::CodeContainer& code, int value)
|
||||
{
|
||||
code.push_back (segment0 (0, value));
|
||||
}
|
||||
|
||||
void opFetchIntLiteral (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (segment5 (4));
|
||||
}
|
||||
|
||||
void opFetchFloatLiteral (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (segment5 (5));
|
||||
}
|
||||
|
||||
void opIntToFloat (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (segment5 (3));
|
||||
}
|
||||
|
||||
void opStoreLocalShort (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (segment5 (0));
|
||||
}
|
||||
|
||||
void opStoreLocalLong (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (segment5 (1));
|
||||
}
|
||||
|
||||
void opStoreLocalFloat (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (segment5 (2));
|
||||
}
|
||||
}
|
||||
|
||||
namespace Compiler
|
||||
{
|
||||
namespace Generator
|
||||
{
|
||||
void assignIntToLocal (CodeContainer& code, Literals& literals, char localType,
|
||||
int localIndex, int value)
|
||||
{
|
||||
int index = literals.addInteger (value);
|
||||
|
||||
opPushInt (code, localIndex);
|
||||
opPushInt (code, index);
|
||||
opFetchIntLiteral (code);
|
||||
|
||||
switch (localType)
|
||||
{
|
||||
case 'f':
|
||||
|
||||
opIntToFloat (code);
|
||||
opStoreLocalFloat (code);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
|
||||
opStoreLocalShort (code);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
|
||||
opStoreLocalLong (code);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
assert (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
#ifndef COMPILER_GENERATOR_H_INCLUDED
|
||||
#define COMPILER_GENERATOR_H_INCLUDED
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <components/interpreter/types.hpp>
|
||||
|
||||
namespace Compiler
|
||||
{
|
||||
class Literals;
|
||||
|
||||
namespace Generator
|
||||
{
|
||||
typedef std::vector<Interpreter::Type_Code> CodeContainer;
|
||||
|
||||
void assignIntToLocal (CodeContainer& code, Literals& literals, char localType,
|
||||
int localIndex, int value);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,62 @@
|
||||
Note: a word is considered to be 32 bit long.
|
||||
|
||||
Header (4 words):
|
||||
word: number of words in code block
|
||||
word: number of words in integer literal block
|
||||
word: number of words in float literal block
|
||||
word: number of words in string literal block
|
||||
|
||||
Body (variable length):
|
||||
code block
|
||||
integer literal block (contains a collection of 1 word long integers)
|
||||
float literal block (contains a collection of 1 word long floating point numbers)
|
||||
string literal block (contains a collection of strings of variable length, word-padded)
|
||||
|
||||
Code bit-patterns:
|
||||
|
||||
3322222222221111111111
|
||||
10987654321098765432109876543210
|
||||
00ccccccAAAAAAAAAAAAAAAAAAAAAAAA segment 0: 64 opcodes, 1 24-bit argument
|
||||
01ccccccAAAAAAAAAAAABBBBBBBBBBBB segment 1: 64 opcodes, 2 12-bit arguments
|
||||
10ccccccccccAAAAAAAAAAAAAAAAAAAA segment 2: 1024 opcodes, 1 20-bit argument
|
||||
110000ccccccccccAAAAAAAAAAAAAAAA segment 3: 1024 opcodes, 1 16-bit argument
|
||||
110001ccccccccccAAAAAAAABBBBBBBB segment 4: 1024 opcodes, 2 8-bit arguments
|
||||
110010cccccccccccccccccccccccccc segment 5: 67108864 opcodes, no arguments
|
||||
other bit-patterns reserved
|
||||
|
||||
legent:
|
||||
c: code
|
||||
A: argument 0
|
||||
B: argument 1
|
||||
|
||||
Segment 0:
|
||||
op 0: push A
|
||||
opcodes 1-31 unused
|
||||
opcodes 32-63 reserved for extensions
|
||||
|
||||
Segment 1:
|
||||
opcodes 0-31 unused
|
||||
opcodes 32-63 reserved for extensions
|
||||
|
||||
Segment 2:
|
||||
opcodes 0-511 unused
|
||||
opcodes 512-1023 reserved for extensions
|
||||
|
||||
Segment 3:
|
||||
opcodes 0-511 unused
|
||||
opcodes 512-1023 reserved for extensions
|
||||
|
||||
Segment 4:
|
||||
opcodes 0-511 unused
|
||||
opcodes 512-1023 reserved for extensions
|
||||
|
||||
Segment 5:
|
||||
op 0: store stack[0] in local short stack[1] and pop twice
|
||||
op 1: store stack[0] in local long stack[1] and pop twice
|
||||
op 2: store stack[0] in local float stack[1] and pop twice
|
||||
op 3: convert stack[0] from integer to float
|
||||
op 4: replace stack[0] with integer literal index stack[0]
|
||||
op 5: replace stack[0] with float literal index stack[0]
|
||||
opcodes 6-33554431 unused
|
||||
opcodes 33554432-67108863 reserved for extensions
|
||||
|
Loading…
Reference in New Issue