Skip to content

Commit

Permalink
[add] write directives.
Browse files Browse the repository at this point in the history
  • Loading branch information
asxez committed Mar 7, 2024
1 parent 5011f8e commit d40c0b5
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
88 changes: 88 additions & 0 deletions compiler/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,94 @@ struct compileUnit {
Parser *curParser; //当前parser
};

//把opcode定义到数组opCodeSlotsUsed中
#define OPCODE_SLOTS(opcode, effect) effect,
static const int opCodeSlotsUsed[] = {
#include "../vm/opcode.inc"
};
#undef OPCODE_SLOTS

//初始化CompileUnit
static void initCompileUnit(Parser *parser, CompileUnit *cu, CompileUnit *enclosingUnit, bool isMethod) {
parser->curCompileUnit = cu;
cu->curParser = parser;
cu->enclosingUnit = enclosingUnit;
cu->curLoop = NULL;
cu->enclosingClassBK = NULL;

//若无外层,说明当前属于模块作用域
if (enclosingUnit == NULL) {
//编译代码时是从上到下从最外层的模块作用域开始,模块作用域设为-1
cu->scopeDepth = -1;
//模块级作用域中没有局部变量
cu->localVarNum = 0;
} else { //若是内层单元,属于局部作用域
if (isMethod) { //若是类中的方法
//若是类的方法就设定隐式self为第0个局部变量,即实例对象,它是方法(消息)的接收者,self这种特殊对象被处理为局部变量
cu->localVars[0].name = "self";
cu->localVars[0].length = 4;
} else { //普通函数
//空出第0个局部变量,保持统一
cu->localVars[0].name = NULL;
cu->localVars[0].length = 0;
}

//第0个局部变量的特殊性使其作用域为模块级别
cu->localVars[0].scopeDepth = -1;
cu->localVars[0].isUpvalue = false;
cu->localVarNum = 1; //localVars[0]被分配
//对于函数和方法来说,初始作用域就是局部作用域
//0表示局部作用域的最外层
cu->scopeDepth = 0;
}

//局部变量保存在栈中,初始时栈中已使用的slot数量等于局部变量的数量
cu->stackSlotNum = cu->localVarNum;
cu->fun = newObjFun(cu->curParser->vm, cu->curParser->curModule, cu->localVarNum);
}

//往函数的指令流中写入1个字节,返回其索引
static int writeByte(CompileUnit *cu, int byte) {
//若在调试状态,额外在debug->lineNo中写入当前token行号
#if DEBUG
IntBufferAdd(cu->curParser->vm, &cu->fun->debug->lineNo, cu->curParser->preToken.lineNo);
#endif
ByteBufferAdd(cu->curParser->vm, &cu->fun->instrStream, (uint8_t) byte);
return (int) (cu->fun->instrStream.count - 1);
}

//写入操作码
static void writeOpCode(CompileUnit *cu, OpCode opCode) {
writeByte(cu, opCode);
//累计需要的运行时空间大小
cu->stackSlotNum += opCodeSlotsUsed[opCode];
if (cu->stackSlotNum > cu->fun->maxStackSlotUsedNum)
cu->fun->maxStackSlotUsedNum = cu->stackSlotNum;
}

//写入1个字节的操作数
static int writeByteOperand(CompileUnit *cu, int operand) {
return writeByte(cu, operand);
}

//写入两个字节的操作数,按大端字节序写入参数,低地址写高位,高地址写低位
static void writeShortOperand(CompileUnit *cu, int operand) {
writeByte(cu, (operand >> 8) & 0xff); //写高8位
writeByte(cu, operand & 0xff); //写低8位
}

//写入操作数为1字节大小的指令
static int writeOpCodeByteOperand(CompileUnit *cu, OpCode opCode, int operand) {
writeOpCode(cu, opCode);
return writeByteOperand(cu, operand);
}

//写入操作数为2字节大小的指令
static void writeOpCodeShortOperand(CompileUnit *cu, OpCode opCode, int operand) {
writeOpCode(cu, opCode);
writeShortOperand(cu, operand);
}

//在模块objModule中定义名为name,值为value的模块变量
int defineModuleVar(VM *vm, ObjModule *objModule, const char *name, uint32_t length, Value value) {
if (length > MAX_ID_LEN) {
Expand Down
5 changes: 5 additions & 0 deletions lexicalParser/include/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "../../utils/common.h"
#include "../../vm/vm.h"
#include "../../objectAndClass/include/meta_obj.h"
#include "../../compiler/compiler.h"

typedef enum {
TOKEN_UNKNOWN,
Expand Down Expand Up @@ -102,10 +103,14 @@ struct parser {
Token curToken; //当前token
Token preToken; //前一个token
ObjModule *curModule; //当前正在编译的模块
CompileUnit *curCompileUnit; //当前编译单元
//词法分析器在任何时刻都会处于一个编译单元中,模块、方法、函数都有自己的编译单元。
//类没有编译单元,因为编译单元是独立的指令流单位,类是由方法组成的,方法才是指令流的单位,类中不允许定义变量,方法中才可以有变量定义,因从类只是方法的编译单元的集合。

//处于内嵌表达式中时,期望的右括号数量
//用于跟踪小括号对的嵌套
int interpolationExpectRightParenNum;
struct parser *parent; //父parser
VM *vm;
};

Expand Down

0 comments on commit d40c0b5

Please sign in to comment.