- implemented all assign/modify operators.

- use a table to translate from PEX to tokens to make the code easier to read.
This commit is contained in:
Christoph Oelckers 2016-10-21 14:18:31 +02:00
parent 3e995d7aac
commit 9f260983c7
3 changed files with 120 additions and 90 deletions

View file

@ -1550,7 +1550,7 @@ FxExpression *FxSizeAlign::Resolve(FCompileContext& ctx)
} }
else else
{ {
FxExpression *x = new FxConstant(Which == 'a' ? int(type->Align) : int(type->Size), Operand->ScriptPosition); FxExpression *x = new FxConstant(Which == TK_AlignOf ? int(type->Align) : int(type->Size), Operand->ScriptPosition);
delete this; delete this;
return x->Resolve(ctx); return x->Resolve(ctx);
} }
@ -1811,12 +1811,12 @@ ExpEmit FxAssign::Emit(VMFunctionBuilder *build)
assert(ValueType == Base->ValueType && IsNumeric()); assert(ValueType == Base->ValueType && IsNumeric());
assert(ValueType->GetRegType() == Right->ValueType->GetRegType()); assert(ValueType->GetRegType() == Right->ValueType->GetRegType());
ExpEmit result = Right->Emit(build);
assert(result.RegType <= REGT_TYPE);
ExpEmit pointer = Base->Emit(build); ExpEmit pointer = Base->Emit(build);
Address = pointer; Address = pointer;
ExpEmit result = Right->Emit(build);
assert(result.RegType <= REGT_TYPE);
if (pointer.Target) if (pointer.Target)
{ {
if (result.Konst) if (result.Konst)

View file

@ -2324,6 +2324,33 @@ FxExpression *ZCCCompiler::ConvertAST(ZCC_TreeNode *ast)
} }
} }
#define xx(a,z) z,
static int Pex2Tok[] = {
#include "zcc_exprlist.h"
};
//==========================================================================
//
// Helper for modify/assign operators
//
//==========================================================================
static FxExpression *ModifyAssign(FxBinary *operation, FxExpression *left)
{
auto assignself = static_cast<FxAssignSelf *>(operation->left);
auto assignment = new FxAssign(left, operation);
assignself->Assignment = assignment;
return assignment;
}
//==========================================================================
//
// Convert an AST node and its children
//
//==========================================================================
FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast) FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
{ {
// Note: Do not call 'Simplify' here because that function tends to destroy identifiers due to lack of context in which to resolve them. // Note: Do not call 'Simplify' here because that function tends to destroy identifiers due to lack of context in which to resolve them.
@ -2426,11 +2453,11 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
{ {
case PEX_PostDec: case PEX_PostDec:
case PEX_PostInc: case PEX_PostInc:
return new FxPostIncrDecr(operand, op == PEX_PostDec ? TK_Decr : TK_Incr); return new FxPostIncrDecr(operand, Pex2Tok[op]);
case PEX_PreDec: case PEX_PreDec:
case PEX_PreInc: case PEX_PreInc:
return new FxPreIncrDecr(operand, op == PEX_PostDec ? TK_Decr : TK_Incr); return new FxPreIncrDecr(operand, Pex2Tok[op]);
case PEX_Negate: case PEX_Negate:
return new FxMinusSign(operand); return new FxMinusSign(operand);
@ -2446,7 +2473,7 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
case PEX_SizeOf: case PEX_SizeOf:
case PEX_AlignOf: case PEX_AlignOf:
return new FxSizeAlign(operand, op == PEX_AlignOf ? 'a' : 's'); return new FxSizeAlign(operand, Pex2Tok[op]);
default: default:
assert(0 && "Unknown unary operator."); // should never happen assert(0 && "Unknown unary operator."); // should never happen
@ -2463,16 +2490,17 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
auto left = ConvertNode(binary->Left); auto left = ConvertNode(binary->Left);
auto right = ConvertNode(binary->Right); auto right = ConvertNode(binary->Right);
auto op = binary->Operation; auto op = binary->Operation;
auto tok = Pex2Tok[op];
switch (op) switch (op)
{ {
case PEX_Add: case PEX_Add:
case PEX_Sub: case PEX_Sub:
return new FxAddSub(op == PEX_Add ? '+' : '-', left, right); return new FxAddSub(tok, left, right);
case PEX_Mul: case PEX_Mul:
case PEX_Div: case PEX_Div:
case PEX_Mod: case PEX_Mod:
return new FxMulDiv(op == PEX_Mul ? '*' : op == PEX_Div ? '/' : '%', left, right); return new FxMulDiv(tok, left, right);
case PEX_Pow: case PEX_Pow:
return new FxPow(left, right); return new FxPow(left, right);
@ -2483,39 +2511,41 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
case PEX_BitAnd: case PEX_BitAnd:
case PEX_BitOr: case PEX_BitOr:
case PEX_BitXor: case PEX_BitXor:
return new FxBinaryInt(op == PEX_LeftShift ? TK_LShift : op == PEX_RightShift ? TK_RShift : op == PEX_URightShift ? TK_URShift : op == PEX_BitAnd ? '&' : op == PEX_BitOr ? '|' : '^', left, right); return new FxBinaryInt(tok, left, right);
case PEX_BoolOr: case PEX_BoolOr:
case PEX_BoolAnd: case PEX_BoolAnd:
return new FxBinaryLogical(op == PEX_BoolAnd ? TK_AndAnd : TK_OrOr, left, right); return new FxBinaryLogical(tok, left, right);
case PEX_LT: case PEX_LT:
case PEX_LTEQ: case PEX_LTEQ:
case PEX_GT: case PEX_GT:
case PEX_GTEQ: case PEX_GTEQ:
return new FxCompareRel(op == PEX_LT ? '<' : op == PEX_RightShift ? '>' : op == PEX_LTEQ ? TK_Leq : TK_Geq, left, right); return new FxCompareRel(tok, left, right);
case PEX_EQEQ: case PEX_EQEQ:
case PEX_NEQ: case PEX_NEQ:
return new FxCompareEq(op == PEX_NEQ ? TK_Neq : TK_Eq, left, right); return new FxCompareEq(tok, left, right);
case PEX_Assign: case PEX_Assign:
return new FxAssign(left, right); return new FxAssign(left, right);
/*
case ZCC_MULEQ: case PEX_AddAssign:
case ZCC_DIVEQ: case PEX_SubAssign:
case ZCC_MODEQ: return ModifyAssign(new FxAddSub(tok, new FxAssignSelf(*ast), right), left);
case ZCC_ADDEQ:
case ZCC_SUBEQ: case PEX_MulAssign:
case ZCC_LSHEQ: case PEX_DivAssign:
case ZCC_RSHEQ: case PEX_ModAssign:
case ZCC_ANDEQ: return ModifyAssign(new FxMulDiv(tok, new FxAssignSelf(*ast), right), left);
case ZCC_OREQ:
case ZCC_XOREQ: case PEX_LshAssign:
//break; case PEX_RshAssign:
default: case PEX_URshAssign:
Error(ast, "Invalid assign statement"); case PEX_AndAssign:
*/ case PEX_OrAssign:
case PEX_XorAssign:
return ModifyAssign(new FxBinaryInt(tok, new FxAssignSelf(*ast), right), left);
// todo: These do not have representations in DECORATE and no implementation exists yet. // todo: These do not have representations in DECORATE and no implementation exists yet.
case PEX_LTGTEQ: case PEX_LTGTEQ:

View file

@ -1,75 +1,75 @@
// Name n-ary // Name Token used in the code generator
xx(Nil, ) xx(Nil, TK_None)
xx(ID, ) xx(ID, TK_Identifier)
xx(Super, ) xx(Super, TK_Super)
xx(Null, ) xx(Null, TK_Null)
xx(Self, ) xx(Self, TK_Self)
xx(ConstValue, ) xx(ConstValue, TK_Const)
xx(FuncCall, ) xx(FuncCall, '(')
xx(ArrayAccess, ) xx(ArrayAccess, TK_Array)
xx(MemberAccess, ) xx(MemberAccess, '.')
xx(TypeRef, ) xx(TypeRef, TK_Class)
xx(PostInc, ) xx(PostInc, TK_Incr)
xx(PostDec, ) xx(PostDec, TK_Decr)
xx(PreInc, ) xx(PreInc, TK_Incr)
xx(PreDec, ) xx(PreDec, TK_Decr)
xx(Negate, ) xx(Negate, '-')
xx(AntiNegate, ) xx(AntiNegate, '+')
xx(BitNot, ) xx(BitNot, '~')
xx(BoolNot, ) xx(BoolNot, '!')
xx(SizeOf, ) xx(SizeOf, TK_SizeOf)
xx(AlignOf, ) xx(AlignOf, TK_AlignOf)
xx(Add, ) xx(Add, '+')
xx(Sub, ) xx(Sub, '-')
xx(Mul, ) xx(Mul, '*')
xx(Div, ) xx(Div, '/')
xx(Mod, ) xx(Mod, '%')
xx(Pow, ) xx(Pow, TK_MulMul)
xx(CrossProduct, ) xx(CrossProduct, TK_Cross)
xx(DotProduct, ) xx(DotProduct, TK_Dot)
xx(LeftShift, ) xx(LeftShift, TK_LShift)
xx(RightShift, ) xx(RightShift, TK_RShift)
xx(URightShift, ) xx(URightShift, TK_URShift)
xx(Concat, ) xx(Concat, TK_DotDot)
xx(LT, ) xx(LT, '<')
xx(LTEQ, ) xx(LTEQ, TK_Leq)
xx(GT, ) xx(GT, '>')
xx(GTEQ, ) xx(GTEQ, TK_Geq)
xx(LTGTEQ, ) xx(LTGTEQ, TK_LtGtEq)
xx(Is, ) xx(Is, TK_Is)
xx(EQEQ, ) xx(EQEQ, TK_Eq)
xx(NEQ, ) xx(NEQ, TK_Neq)
xx(APREQ, ) xx(APREQ, TK_ApproxEq)
xx(BitAnd, ) xx(BitAnd, '&')
xx(BitOr, ) xx(BitOr, '|')
xx(BitXor, ) xx(BitXor, '^')
xx(BoolAnd, ) xx(BoolAnd, TK_AndAnd)
xx(BoolOr, ) xx(BoolOr, TK_OrOr)
xx(Assign, ) xx(Assign, '=')
xx(AddAssign, ) xx(AddAssign, '+') // these are what the code generator needs, not what they represent.
xx(SubAssign, ) xx(SubAssign, '-')
xx(MulAssign, ) xx(MulAssign, '*')
xx(DivAssign, ) xx(DivAssign, '/')
xx(ModAssign, ) xx(ModAssign, '%')
xx(LshAssign, ) xx(LshAssign, TK_LShift)
xx(RshAssign, ) xx(RshAssign, TK_RShift)
xx(URshAssign, ) xx(URshAssign, TK_URShift)
xx(AndAssign, ) xx(AndAssign, '&')
xx(OrAssign, ) xx(OrAssign, '|')
xx(XorAssign, ) xx(XorAssign, '^')
xx(Scope, ) xx(Scope, TK_ColonColon)
xx(Trinary, ) xx(Trinary, '?')
xx(Cast, ) xx(Cast, TK_Coerce)
#undef xx #undef xx