mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-28 06:42:09 +00:00
- tested and fixed the regular assignment statement for both local and member variables.
The generated object code can definitely use an optimization pass but that's something left for later when more things are working. Right now it creates one opcode more than necessary for all member accesses (instead of using the offset in the store command it calculates an actual address of the variable in another address register) and can create one too many for non-constant expressions being assigned to local variables (a move between two registers because the emitted expression on the right hand side does not know that it can emit to the actual variable's register.)
This commit is contained in:
parent
9f99ca4788
commit
1450c3dffb
4 changed files with 40 additions and 35 deletions
|
@ -179,7 +179,7 @@ FxLocalVariableDeclaration *FCompileContext::FindLocalVariable(FName name)
|
|||
//==========================================================================
|
||||
|
||||
ExpEmit::ExpEmit(VMFunctionBuilder *build, int type)
|
||||
: RegNum(build->Registers[type].Get(1)), RegType(type), Konst(false), Fixed(false), Final(false)
|
||||
: RegNum(build->Registers[type].Get(1)), RegType(type), Konst(false), Fixed(false), Final(false), Target(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1807,16 +1807,16 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx)
|
|||
|
||||
ExpEmit FxAssign::Emit(VMFunctionBuilder *build)
|
||||
{
|
||||
static const BYTE loadops[] = { OP_NOP, OP_LK, OP_LKF, OP_LKS, OP_LKP };
|
||||
static const BYTE loadops[] = { OP_LK, OP_LKF, OP_LKS, OP_LKP };
|
||||
assert(ValueType == Base->ValueType && IsNumeric());
|
||||
assert(ValueType->GetRegType() == Right->ValueType->GetRegType());
|
||||
|
||||
ExpEmit pointer = Base->Emit(build);
|
||||
Address = pointer;
|
||||
|
||||
ExpEmit result = Right->Emit(build);
|
||||
assert(result.RegType <= REGT_TYPE);
|
||||
|
||||
ExpEmit pointer = Base->Emit(build);
|
||||
Address = pointer;
|
||||
|
||||
if (pointer.Target)
|
||||
{
|
||||
if (result.Konst)
|
||||
|
@ -4025,6 +4025,7 @@ FxLocalVariable::FxLocalVariable(FxLocalVariableDeclaration *var, const FScriptP
|
|||
: FxExpression(sc)
|
||||
{
|
||||
Variable = var;
|
||||
ValueType = var->ValueType;
|
||||
AddressRequested = false;
|
||||
}
|
||||
|
||||
|
@ -5167,7 +5168,7 @@ FxExpression *FxCompoundStatement::Resolve(FCompileContext &ctx)
|
|||
ctx.Block = this;
|
||||
auto x = FxSequence::Resolve(ctx);
|
||||
ctx.Block = outer;
|
||||
return this;
|
||||
return x;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -193,8 +193,8 @@ struct ExpVal
|
|||
|
||||
struct ExpEmit
|
||||
{
|
||||
ExpEmit() : RegNum(0), RegType(REGT_NIL), Konst(false), Fixed(false), Final(false) {}
|
||||
ExpEmit(int reg, int type, bool konst = false, bool fixed = false) : RegNum(reg), RegType(type), Konst(konst), Fixed(fixed), Final(false) {}
|
||||
ExpEmit() : RegNum(0), RegType(REGT_NIL), Konst(false), Fixed(false), Final(false), Target(false) {}
|
||||
ExpEmit(int reg, int type, bool konst = false, bool fixed = false) : RegNum(reg), RegType(type), Konst(konst), Fixed(fixed), Final(false), Target(false) {}
|
||||
ExpEmit(VMFunctionBuilder *build, int type);
|
||||
void Free(VMFunctionBuilder *build);
|
||||
void Reuse(VMFunctionBuilder *build);
|
||||
|
|
|
@ -682,6 +682,10 @@ void FFunctionBuildList::Build()
|
|||
|
||||
for (auto &item : mItems)
|
||||
{
|
||||
if (item.PrintableName.CompareNoCase("Middle.StateFunction.3") == 0)
|
||||
{
|
||||
int a = 0;
|
||||
}
|
||||
assert(item.Code != NULL);
|
||||
|
||||
// We don't know the return type in advance for anonymous functions.
|
||||
|
|
|
@ -2354,6 +2354,25 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
|
|||
// todo.
|
||||
break;
|
||||
|
||||
case AST_ExprBinary:
|
||||
// Array syntax for randoms. They are internally stored as ExprBinary with both an identifier on the left and right side.
|
||||
if (fcall->Function->Operation == PEX_ArrayAccess)
|
||||
{
|
||||
auto binary = static_cast<ZCC_ExprBinary *>(fcall->Function);
|
||||
if (binary->Left->NodeType == AST_ExprID && binary->Right->NodeType == AST_ExprID)
|
||||
{
|
||||
return new FxFunctionCall(static_cast<ZCC_ExprID *>(binary->Left)->Identifier, static_cast<ZCC_ExprID *>(binary->Right)->Identifier, ConvertNodeList(fcall->Parameters), *ast);
|
||||
}
|
||||
}
|
||||
// fall through if this isn't an array access node.
|
||||
|
||||
default:
|
||||
Error(fcall, "Invalid function identifier");
|
||||
return new FxNop(*ast); // return something so that the compiler can continue.
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case AST_AssignStmt:
|
||||
{
|
||||
auto assign = static_cast<ZCC_AssignStmt *>(ast);
|
||||
|
@ -2381,25 +2400,6 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
|
|||
break;
|
||||
}
|
||||
|
||||
case AST_ExprBinary:
|
||||
// Array syntax for randoms. They are internally stored as ExprBinary with both an identifier on the left and right side.
|
||||
if (fcall->Function->Operation == PEX_ArrayAccess)
|
||||
{
|
||||
auto binary = static_cast<ZCC_ExprBinary *>(fcall->Function);
|
||||
if (binary->Left->NodeType == AST_ExprID && binary->Right->NodeType == AST_ExprID)
|
||||
{
|
||||
return new FxFunctionCall(static_cast<ZCC_ExprID *>(binary->Left)->Identifier, static_cast<ZCC_ExprID *>(binary->Right)->Identifier, ConvertNodeList(fcall->Parameters), *ast);
|
||||
}
|
||||
}
|
||||
// fall through if this isn't an array access node.
|
||||
|
||||
default:
|
||||
Error(fcall, "Invalid function identifier");
|
||||
return new FxNop(*ast); // return something so that the compiler can continue.
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case AST_FuncParm:
|
||||
{
|
||||
auto fparm = static_cast<ZCC_FuncParm *>(ast);
|
||||
|
|
Loading…
Reference in a new issue