qzdoom/src/zscript/ast.cpp

612 lines
15 KiB
C++

#include "dobject.h"
#include "sc_man.h"
#include "memarena.h"
#include "zcc_parser.h"
#include "zcc-parse.h"
extern void (* const TreeNodePrinter[NUM_AST_NODE_TYPES])(FString &, ZCC_TreeNode *);
static const char *BuiltInTypeNames[] =
{
"sint8", "uint8",
"sint16", "uint16",
"sint32", "uint32",
"intauto",
"bool",
"float32", "float64", "floatauto",
"string",
"vector2",
"vector3",
"vector4",
"name",
"usertype"
};
static void PrintNode(FString &out, ZCC_TreeNode *node)
{
assert(TreeNodePrinter[NUM_AST_NODE_TYPES-1] != NULL);
if (node->NodeType >= 0 && node->NodeType < NUM_AST_NODE_TYPES)
{
TreeNodePrinter[node->NodeType](out, node);
}
else
{
out.AppendFormat("(unknown-node-type-%d)", node->NodeType);
}
}
static void PrintNodes(FString &out, ZCC_TreeNode *node, char addchar=' ')
{
ZCC_TreeNode *p;
if (node == NULL)
{
out << "nil";
}
else
{
out << '(';
p = node;
do
{
PrintNode(out, p);
p = p->SiblingNext;
if (p != node)
{
out << ' ';
}
} while (p != node);
out << ')';
}
if (addchar != '\0')
{
out << addchar;
}
}
static void PrintBuiltInType(FString &out, EZCCBuiltinType type, bool addspace)
{
assert(ZCC_NUM_BUILT_IN_TYPES == countof(BuiltInTypeNames));
if (unsigned(type) >= unsigned(ZCC_NUM_BUILT_IN_TYPES))
{
out.AppendFormat("bad-type-%u", type);
}
else
{
out << BuiltInTypeNames[type];
}
if (addspace)
{
out << ' ';
}
}
static void PrintIdentifier(FString &out, ZCC_TreeNode *node)
{
ZCC_Identifier *inode = (ZCC_Identifier *)node;
out.AppendFormat("(identifier '%s')", FName(inode->Id).GetChars());
}
static void PrintStringConst(FString &out, FString str)
{
out << '"';
for (size_t i = 0; i < str.Len(); ++i)
{
if (str[i] == '"')
{
out << "\"";
}
else if (str[i] == '\\')
{
out << "\\\\";
}
else if (str[i] >= 32)
{
out << str[i];
}
else
{
out.AppendFormat("\\x%02X", str[i]);
}
}
}
static void PrintClass(FString &out, ZCC_TreeNode *node)
{
ZCC_Class *cnode = (ZCC_Class *)node;
out << "\n(class ";
PrintNodes(out, cnode->ClassName);
PrintNodes(out, cnode->ParentName);
PrintNodes(out, cnode->Replaces);
out.AppendFormat("%08x ", cnode->Flags);
PrintNodes(out, cnode->Body, ')');
}
static void PrintStruct(FString &out, ZCC_TreeNode *node)
{
ZCC_Struct *snode = (ZCC_Struct *)node;
out.AppendFormat("\n(struct '%s' ", FName(snode->StructName).GetChars());
PrintNodes(out, snode->Body, ')');
}
static void PrintEnum(FString &out, ZCC_TreeNode *node)
{
ZCC_Enum *enode = (ZCC_Enum *)node;
out.AppendFormat("\n(enum '%s' ", FName(enode->EnumName).GetChars());
PrintBuiltInType(out, enode->EnumType, true);
PrintNodes(out, enode->Elements, ')');
}
static void PrintEnumNode(FString &out, ZCC_TreeNode *node)
{
ZCC_EnumNode *enode = (ZCC_EnumNode *)node;
out.AppendFormat("(enum-node '%s' ", FName(enode->ElemName).GetChars());
PrintNodes(out, enode->ElemValue, ')');
}
static void PrintStates(FString &out, ZCC_TreeNode *node)
{
ZCC_States *snode = (ZCC_States *)node;
out << "\n(states ";
PrintNodes(out, snode->Body, ')');
}
static void PrintStatePart(FString &out, ZCC_TreeNode *node)
{
out << "(state-part)";
}
static void PrintStateLabel(FString &out, ZCC_TreeNode *node)
{
ZCC_StateLabel *snode = (ZCC_StateLabel *)node;
out.AppendFormat("\n(state-label '%s')", FName(snode->Label).GetChars());
}
static void PrintStateStop(FString &out, ZCC_TreeNode *node)
{
out << "(state-stop)";
}
static void PrintStateWait(FString &out, ZCC_TreeNode *node)
{
out << "(state-wait)";
}
static void PrintStateFail(FString &out, ZCC_TreeNode *node)
{
out << "(state-fail)";
}
static void PrintStateLoop(FString &out, ZCC_TreeNode *node)
{
out << "(state-loop)";
}
static void PrintStateGoto(FString &out, ZCC_TreeNode *node)
{
ZCC_StateGoto *snode = (ZCC_StateGoto *)node;
out << "(state-goto ";
PrintNodes(out, snode->Label);
PrintNodes(out, snode->Offset, ')');
}
static void PrintStateLine(FString &out, ZCC_TreeNode *node)
{
ZCC_StateLine *snode = (ZCC_StateLine *)node;
out.AppendFormat("\n(state-line %c%c%c%c %s %s ",
snode->Sprite[0], snode->Sprite[1], snode->Sprite[2], snode->Sprite[3],
snode->bBright ? "bright " : "",
snode->Frames->GetChars());
PrintNodes(out, snode->Offset);
PrintNodes(out, snode->Action, ')');
}
static void PrintVarName(FString &out, ZCC_TreeNode *node)
{
ZCC_VarName *vnode = (ZCC_VarName *)node;
out.AppendFormat("(var-name '%s')", FName(vnode->Name).GetChars());
}
static void PrintType(FString &out, ZCC_TreeNode *node)
{
ZCC_Type *tnode = (ZCC_Type *)node;
out << "(bad-type ";
PrintNodes(out, tnode->ArraySize, ')');
}
static void PrintBasicType(FString &out, ZCC_TreeNode *node)
{
ZCC_BasicType *tnode = (ZCC_BasicType *)node;
out << "(basic-type ";
PrintNodes(out, tnode->ArraySize);
PrintBuiltInType(out, tnode->Type, true);
PrintNodes(out, tnode->UserType, ')');
}
static void PrintMapType(FString &out, ZCC_TreeNode *node)
{
ZCC_MapType *tnode = (ZCC_MapType *)node;
out << "(map-type ";
PrintNodes(out, tnode->ArraySize);
PrintNodes(out, tnode->KeyType);
PrintNodes(out, tnode->ValueType, ')');
}
static void PrintDynArrayType(FString &out, ZCC_TreeNode *node)
{
ZCC_DynArrayType *tnode = (ZCC_DynArrayType *)node;
out << "(dyn-array-type ";
PrintNodes(out, tnode->ArraySize);
PrintNodes(out, tnode->ElementType, ')');
}
static void PrintClassType(FString &out, ZCC_TreeNode *node)
{
ZCC_ClassType *tnode = (ZCC_ClassType *)node;
out << "(class-type ";
PrintNodes(out, tnode->ArraySize);
PrintNodes(out, tnode->Restriction, ')');
}
static void PrintExprType(FString &out, EZCCExprType type)
{
static const char *const types[] =
{
"nil ",
"id ",
"super ",
"self ",
"string-const ",
"int-const ",
"uint-const ",
"float-const ",
"func-call ",
"array-access ",
"member-access ",
"post-inc ",
"post-dec ",
"pre-inc ",
"pre-dec ",
"negate ",
"anti-negate ",
"bit-not ",
"bool-not ",
"size-of ",
"align-of ",
"add ",
"sub ",
"mul ",
"div ",
"mod ",
"pow ",
"cross-product ",
"dot-product ",
"left-shift ",
"right-shift ",
"concat ",
"lt ",
"gt ",
"lteq ",
"gteq ",
"ltgteq ",
"is ",
"eqeq ",
"neq ",
"apreq ",
"bit-and ",
"bit-or ",
"bit-xor ",
"bool-and ",
"bool-or ",
"scope ",
"trinary ",
};
assert(countof(types) == PEX_COUNT_OF);
if (unsigned(type) < countof(types))
{
out << types[type];
}
else
{
out.AppendFormat("bad-pex-%u ", type);
}
}
static void PrintExpression(FString &out, ZCC_TreeNode *node)
{
ZCC_Expression *enode = (ZCC_Expression *)node;
out << "(expr-";
PrintExprType(out, enode->Operation);
out << ')';
}
static void PrintExprID(FString &out, ZCC_TreeNode *node)
{
ZCC_ExprID *enode = (ZCC_ExprID *)node;
assert(enode->Operation == PEX_ID);
out.AppendFormat("(expr-id '%s')", FName(enode->Identifier).GetChars());
}
static void PrintExprString(FString &out, ZCC_TreeNode *node)
{
ZCC_ExprString *enode = (ZCC_ExprString *)node;
assert(enode->Operation == PEX_StringConst);
out.AppendFormat("(expr-string-const ");
PrintStringConst(out, *enode->Value);
out << ')';
}
static void PrintExprInt(FString &out, ZCC_TreeNode *node)
{
ZCC_ExprInt *enode = (ZCC_ExprInt *)node;
assert(enode->Operation == PEX_IntConst || enode->Operation == PEX_UIntConst);
out << "(expr-";
PrintExprType(out, enode->Operation);
out.AppendFormat("%d)", enode->Value);
}
static void PrintExprFloat(FString &out, ZCC_TreeNode *node)
{
ZCC_ExprFloat *enode = (ZCC_ExprFloat *)node;
assert(enode->Operation == PEX_FloatConst);
out.AppendFormat("(expr-float-const %g)", enode->Value);
}
static void PrintExprFuncCall(FString &out, ZCC_TreeNode *node)
{
ZCC_ExprFuncCall *enode = (ZCC_ExprFuncCall *)node;
assert(enode->Operation == PEX_FuncCall);
out << "(expr-func-call ";
PrintNodes(out, enode->Function);
PrintNodes(out, enode->Parameters, ')');
}
static void PrintExprMemberAccess(FString &out, ZCC_TreeNode *node)
{
ZCC_ExprMemberAccess *enode = (ZCC_ExprMemberAccess *)node;
assert(enode->Operation == PEX_MemberAccess);
out << "(expr-member-access ";
PrintNodes(out, enode->Left);
out.AppendFormat("'%s')", FName(enode->Right).GetChars());
}
static void PrintExprUnary(FString &out, ZCC_TreeNode *node)
{
ZCC_ExprUnary *enode = (ZCC_ExprUnary *)node;
out << "(expr-";
PrintExprType(out, enode->Operation);
PrintNodes(out, enode->Operand, ')');
}
static void PrintExprBinary(FString &out, ZCC_TreeNode *node)
{
ZCC_ExprBinary *enode = (ZCC_ExprBinary *)node;
out << "(expr-";
PrintExprType(out, enode->Operation);
PrintNodes(out, enode->Left);
PrintNodes(out, enode->Right, ')');
}
static void PrintExprTrinary(FString &out, ZCC_TreeNode *node)
{
ZCC_ExprTrinary *enode = (ZCC_ExprTrinary *)node;
out << "(expr-";
PrintExprType(out, enode->Operation);
PrintNodes(out, enode->Test);
PrintNodes(out, enode->Left);
PrintNodes(out, enode->Right, ')');
}
static void PrintFuncParam(FString &out, ZCC_TreeNode *node)
{
ZCC_FuncParm *pnode = (ZCC_FuncParm *)node;
out.AppendFormat("(func-parm %s ", FName(pnode->Label).GetChars());;
PrintNodes(out, pnode->Value, ')');
}
static void PrintStatement(FString &out, ZCC_TreeNode *node)
{
out << "(statement)";
}
static void PrintCompoundStmt(FString &out, ZCC_TreeNode *node)
{
ZCC_CompoundStmt *snode = (ZCC_CompoundStmt *)node;
out << "(compound-stmt ";
PrintNodes(out, snode->Content, ')');
}
static void PrintContinueStmt(FString &out, ZCC_TreeNode *node)
{
out << "(continue-stmt)";
}
static void PrintBreakStmt(FString &out, ZCC_TreeNode *node)
{
out << "(break-stmt)";
}
static void PrintReturnStmt(FString &out, ZCC_TreeNode *node)
{
ZCC_ReturnStmt *snode = (ZCC_ReturnStmt *)node;
out << "(return-stmt ";
PrintNodes(out, snode->Values, ')');
}
static void PrintExpressionStmt(FString &out, ZCC_TreeNode *node)
{
ZCC_ExpressionStmt *snode = (ZCC_ExpressionStmt *)node;
out << "(expression-stmt ";
PrintNodes(out, snode->Expression, ')');
}
static void PrintIterationStmt(FString &out, ZCC_TreeNode *node)
{
ZCC_IterationStmt *snode = (ZCC_IterationStmt *)node;
out << "(iteration-stmt ";
out << (snode->CheckAt == ZCC_IterationStmt::Start) ? "start " : "end ";
PrintNodes(out, snode->LoopCondition);
PrintNodes(out, snode->LoopBumper);
PrintNodes(out, snode->LoopStatement, true);
}
static void PrintIfStmt(FString &out, ZCC_TreeNode *node)
{
ZCC_IfStmt *snode = (ZCC_IfStmt *)node;
out << "(if-stmt ";
PrintNodes(out, snode->Condition);
PrintNodes(out, snode->TruePath);
PrintNodes(out, snode->FalsePath, ')');
}
static void PrintSwitchStmt(FString &out, ZCC_TreeNode *node)
{
ZCC_SwitchStmt *snode = (ZCC_SwitchStmt *)node;
out << "(switch-stmt ";
PrintNodes(out, snode->Condition);
PrintNodes(out, snode->Content, ')');
}
static void PrintCaseStmt(FString &out, ZCC_TreeNode *node)
{
ZCC_CaseStmt *snode = (ZCC_CaseStmt *)node;
out << "(case-stmt ";
PrintNodes(out, snode->Condition, ')');
}
static void PrintAssignStmt(FString &out, ZCC_TreeNode *node)
{
ZCC_AssignStmt *snode = (ZCC_AssignStmt *)node;
out << "(assign-stmt ";
switch (snode->AssignOp)
{
case ZCC_EQ: out << "= "; break;
case ZCC_MULEQ: out << "*= "; break;
case ZCC_DIVEQ: out << "/= "; break;
case ZCC_MODEQ: out << "%= "; break;
case ZCC_ADDEQ: out << "+= "; break;
case ZCC_SUBEQ: out << "-= "; break;
case ZCC_LSHEQ: out << "<<= "; break;
case ZCC_RSHEQ: out << ">>= "; break;
case ZCC_ANDEQ: out << "&= "; break;
case ZCC_OREQ: out << "|= "; break;
case ZCC_XOREQ: out << "^= "; break;
default:
out.AppendFormat("assign-op-%d ", snode->AssignOp);
}
PrintNodes(out, snode->Dests);
PrintNodes(out, snode->Sources, ')');
}
static void PrintLocalVarStmt(FString &out, ZCC_TreeNode *node)
{
ZCC_LocalVarStmt *snode = (ZCC_LocalVarStmt *)node;
out << "(local-var-stmt ";
PrintNodes(out, snode->Type);
PrintNodes(out, snode->Vars);
PrintNodes(out, snode->Inits, ')');
}
static void PrintFuncParamDecl(FString &out, ZCC_TreeNode *node)
{
ZCC_FuncParamDecl *dnode = (ZCC_FuncParamDecl *)node;
out << "(func-param-decl ";
PrintNodes(out, dnode->Type);
out.AppendFormat("%s %x)", FName(dnode->Name).GetChars(), dnode->Flags);
}
static void PrintConstantDef(FString &out, ZCC_TreeNode *node)
{
ZCC_ConstantDef *dnode = (ZCC_ConstantDef *)node;
out.AppendFormat("(constant-def %s ", FName(dnode->Name).GetChars());
PrintNodes(out, dnode->Value, ')');
}
static void PrintDeclarator(FString &out, ZCC_TreeNode *node)
{
ZCC_Declarator *dnode = (ZCC_Declarator *)node;
out << "(declarator ";
PrintNodes(out, dnode->Type);
out.AppendFormat("%x)", dnode->Flags);
}
static void PrintVarDeclarator(FString &out, ZCC_TreeNode *node)
{
ZCC_VarDeclarator *dnode = (ZCC_VarDeclarator *)node;
out << "\n(var-declarator ";
PrintNodes(out, dnode->Type);
out.AppendFormat("%x ", dnode->Flags);
PrintNodes(out, dnode->Names, ')');
out << '\n';
}
static void PrintFuncDeclarator(FString &out, ZCC_TreeNode *node)
{
ZCC_FuncDeclarator *dnode = (ZCC_FuncDeclarator *)node;
out << "\n(func-declarator ";
PrintNodes(out, dnode->Type);
out.AppendFormat("%x %s ", dnode->Flags, FName(dnode->Name).GetChars());
PrintNodes(out, dnode->Params, ')');
out << '\n';
}
void (* const TreeNodePrinter[NUM_AST_NODE_TYPES])(FString &, ZCC_TreeNode *) =
{
PrintIdentifier,
PrintClass,
PrintStruct,
PrintEnum,
PrintEnumNode,
PrintStates,
PrintStatePart,
PrintStateLabel,
PrintStateStop,
PrintStateWait,
PrintStateFail,
PrintStateLoop,
PrintStateGoto,
PrintStateLine,
PrintVarName,
PrintType,
PrintBasicType,
PrintMapType,
PrintDynArrayType,
PrintClassType,
PrintExpression,
PrintExprID,
PrintExprString,
PrintExprInt,
PrintExprFloat,
PrintExprFuncCall,
PrintExprMemberAccess,
PrintExprUnary,
PrintExprBinary,
PrintExprTrinary,
PrintFuncParam,
PrintStatement,
PrintCompoundStmt,
PrintContinueStmt,
PrintBreakStmt,
PrintReturnStmt,
PrintExpressionStmt,
PrintIterationStmt,
PrintIfStmt,
PrintSwitchStmt,
PrintCaseStmt,
PrintAssignStmt,
PrintLocalVarStmt,
PrintFuncParamDecl,
PrintConstantDef,
PrintDeclarator,
PrintVarDeclarator,
PrintFuncDeclarator
};
FString ZCC_PrintAST(ZCC_TreeNode *root)
{
FString out;
PrintNodes(out, root, '\0');
return out;
}