/*************/ /*GEMWIRE */ /* ERYTHRO*/ /*************/ #include #include /**************************************************************** * Types are enumerated by the DataTypes enum. * * They are represented by unsigned integers, where the * * most significant 28 bits differentiate the raw type * * of the data being encoded. * * However, the least significant nibble - that is, * * the lowest 4 bits, represent the count of indirection. * * * * This means that a raw Integer data type, such as an i32, * * has the DataType representation 32. * * However, a pointer to an Integer has DataType value 32+1, * * or 33. * * * * This means that the maximum valid pointer level is 16. * * That's a: * * ****************int * * That ought to be enough for everyone, right? * * * ****************************************************************/ /* * Adds 1 to the input Type, to add a level of indirection. * If the indirection is already at 16 levels, it aborts. * * @param Type: The DataType to pointerise * @return the new pointerised DataType value. */ int PointerTo(int Type) { if ((Type & 0xf) == 0xf) ErrorReport("Unrecognized type in pointerisation: %d\n", Type); printf("\t\tPointerising a %s\n", TypeNames(Type)); return (Type + 1); } /* * Returns the underlying type behind a pointer. * If the type is not a pointer (the lowest 4 bits are 0), it halts compliation. * * @param Type: The type to un-dereference * @return the underlying Type */ int ValueAt(int Type) { printf("\t\tDereferencing a %s\n", TypeNames(Type)); if ((Type & 0xf) == 0x0) ErrorReport("Unrecognized type in defererencing: %d (%s)\n", Type, TypeNames(Type)); return (Type - 1); } /* * Array Accesses come in the form of x[y]. * * x must be a pointer type, and an array structure. * y can be any binary expression. * * It is a wrapper around *((imax*)x + y). * * @return the AST Node that represents this statement. */ struct ASTNode* AccessArray() { struct ASTNode* LeftNode, * RightNode; struct SymbolTableEntry* Entry; printf("\tAccessing array %s as requested\r\n", CurrentIdentifier); if ((Entry = FindSymbol(CurrentIdentifier)) == NULL || Entry->Structure != ST_ARR) ErrorReport("Accessing undeclared array: %s\n", CurrentIdentifier); LeftNode = ConstructASTLeaf(OP_ADDRESS, Entry->Type, Entry, 0); Tokenise(); RightNode = ParsePrecedenceASTNode(0); VerifyToken(LI_RBRAS, "]"); if (!TypeIsInt(RightNode->ExprType)) ErrorReport("Array index is not integer"); printf("\t\tPreparing types - RightNode of type %s must be mutated to LeftNode type %s\r\n", TypeNames(RightNode->ExprType), TypeNames(LeftNode->ExprType)); RightNode = MutateType(RightNode, LeftNode->ExprType, OP_ADD); LeftNode = ConstructASTNode(OP_ADD, Entry->Type, LeftNode, NULL, RightNode, NULL, 0); printf("\tAccessArray: Preparing LeftNode for dereference.\r\n"); LeftNode = ConstructASTBranch(OP_DEREF, ValueAt(LeftNode->ExprType), LeftNode, Entry, 0); printf("\tArray Access constructed\r\n"); return LeftNode; } /** * Members of enums and structs are accessed with x.y or *x->y * * x must be enum, struct, or pointer to struct. * y must be a valid member of any of the above. * * It is a wrapper around *((imax*)x + xType.ordinal(y)) * * @return the AST Node representing this statement. */ struct ASTNode* AccessMember(bool Deref) { struct ASTNode* LeftNode, * RightNode; struct SymbolTableEntry* CompositeVar, * TypePtr, * Member; if ((CompositeVar = FindSymbol(CurrentIdentifier)) == NULL) ErrorReport("Undeclared variable: %s\n", CurrentIdentifier); if (Deref && (CompositeVar->Type != PointerTo(DAT_STRUCT) && CompositeVar->Type != PointerTo(DAT_UNION))) ErrorReport("Undeclared struct: %s\n", CurrentIdentifier); if (!Deref && (CompositeVar->Type != DAT_STRUCT && CompositeVar->Type != DAT_UNION)) ErrorReport("Undeclared struct: %s\n", CurrentIdentifier); Safe(); if (Deref) LeftNode = ConstructASTLeaf(REF_IDENT, PointerTo(CompositeVar->Type), CompositeVar, 0); else LeftNode = ConstructASTLeaf(OP_ADDRESS, CompositeVar->Type, CompositeVar, 0); LeftNode->RVal = true; TypePtr = CompositeVar->CompositeType; Tokenise(); VerifyToken(TY_IDENTIFIER, "identifier"); for (Member = TypePtr->Start; Member != NULL; Member = Member->NextSymbol) { printf("\tComparing composite entry %s with the wanted %s. Index %d.\r\n", Member->Name, CurrentIdentifier, Member->SinkOffset); if (!strcmp(Member->Name, CurrentIdentifier)) break; } if (Member == NULL) ErrorReport("Invalid composite member: %s\n", CurrentIdentifier); Safe(); RightNode = ConstructASTLeaf(TERM_INTLITERAL, RET_INT, NULL, Member->SinkOffset); LeftNode = ConstructASTNode(OP_ADD, PointerTo(Member->Type), LeftNode, NULL, RightNode, NULL, 0); LeftNode = ConstructASTBranch(OP_DEREF, Member->Type, LeftNode, Member, 0); return LeftNode; }