diff options
-rw-r--r-- | colm.vim | 2 | ||||
-rw-r--r-- | src/bytecode.c | 53 | ||||
-rw-r--r-- | src/bytecode.h | 12 | ||||
-rw-r--r-- | src/colm.lm | 1 | ||||
-rw-r--r-- | src/compiler.cc | 7 | ||||
-rw-r--r-- | src/compiler.h | 5 | ||||
-rw-r--r-- | src/declare.cc | 42 | ||||
-rw-r--r-- | src/loadcolm.cc | 21 | ||||
-rw-r--r-- | src/lookup.cc | 11 | ||||
-rw-r--r-- | src/parser.cc | 16 | ||||
-rw-r--r-- | src/parser.h | 1 | ||||
-rw-r--r-- | src/parsetree.cc | 6 | ||||
-rw-r--r-- | src/parsetree.h | 77 | ||||
-rw-r--r-- | src/program.h | 6 | ||||
-rw-r--r-- | src/resolve.cc | 16 | ||||
-rw-r--r-- | src/synthesis.cc | 60 | ||||
-rw-r--r-- | src/tree.c | 18 | ||||
-rw-r--r-- | src/tree.h | 2 |
18 files changed, 299 insertions, 57 deletions
@@ -67,7 +67,7 @@ syntax keyword typeKeywords syntax keyword Keyword \ reject else elsif return yield for while if \ typeid in break - \ new deref ni cast switch case default + \ new new2 deref ni cast switch case default syntax match tokenName "[a-zA-Z_][a-zA-Z_0-9]*" contained syntax match varCapture "[a-zA-Z_][a-zA-Z_0-9]*:" diff --git a/src/bytecode.c b/src/bytecode.c index 84f448cf..ecd2dea9 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -1307,9 +1307,15 @@ again: debug( prg, REALM_BYTECODE, "IN_GET_LOCAL_R %hd\n", field ); - Tree *val = vm_local(field); - treeUpref( val ); - vm_push( val ); + if ( field > 48 ) { + Tree *val = vm_local(-field - 64); + vm_push( val ); + } + else { + Tree *val = vm_local(field); + treeUpref( val ); + vm_push( val ); + } break; } case IN_GET_LOCAL_WC: { @@ -1318,20 +1324,30 @@ again: debug( prg, REALM_BYTECODE, "IN_GET_LOCAL_WC %hd\n", field ); - Tree *split = getLocalSplit( prg, exec->framePtr, field ); - treeUpref( split ); - vm_push( split ); + if ( field > 48 ) { + Tree *val = exec->framePtr[-field - 64]; + vm_push( val ); + } + else { + Tree *split = getLocalSplit( prg, exec->framePtr, field ); + treeUpref( split ); + vm_push( split ); + } break; } case IN_SET_LOCAL_WC: { short field; read_half( field ); - debug( prg, REALM_BYTECODE, "IN_SET_LOCAL_WC %hd\n", field ); Tree *val = vm_pop(); - treeDownref( prg, sp, vm_local(field) ); - setLocal( exec->framePtr, field, val ); + if ( field > 48 ) { + exec->framePtr[-field - 64] = val; + } + else { + treeDownref( prg, sp, vm_local(field) ); + setLocal( exec->framePtr, field, val ); + } break; } case IN_SAVE_RET: { @@ -1516,6 +1532,15 @@ again: vm_push( obj ); break; } + case IN_NEW_STRUCT: { + short size; + read_half( size ); + + debug( prg, REALM_BYTECODE, "IN_NEW_STRUCT %hd\n", size ); + HeapItem *item = newStruct( prg, size ); + vm_push( (Tree*)item ); + break; + } case IN_GET_STRUCT_FIELD_R: { short field; read_half( field ); @@ -1523,9 +1548,8 @@ again: debug( prg, REALM_BYTECODE, "IN_GET_STRUCT_FIELD_R %d\n", field ); Tree *obj = vm_pop(); - treeDownref( prg, sp, obj ); - Tree *val = getField( obj, field ); + Tree *val = ((Tree**)obj)[2+field]; treeUpref( val ); vm_push( val ); break; @@ -1584,13 +1608,10 @@ again: Tree *obj = vm_pop(); Tree *val = vm_pop(); - treeDownref( prg, sp, obj ); /* Downref the old value. */ - Tree *prev = getField( obj, field ); - treeDownref( prg, sp, prev ); - - setField( prg, obj, field, val ); + treeDownref( prg, sp, ((Tree**)obj)[2+field] ); + ((Tree**)obj)[2+field] = val; break; } case IN_SET_STRUCT_FIELD_WV: { diff --git a/src/bytecode.h b/src/bytecode.h index 4c16533c..b7af7d02 100644 --- a/src/bytecode.h +++ b/src/bytecode.h @@ -332,14 +332,16 @@ typedef unsigned char uchar; #define IN_SET_STRUCT_FIELD_WC 0xfb #define IN_SET_STRUCT_FIELD_WV 0xfc #define IN_SET_STRUCT_FIELD_BKT 0xfd +#define IN_NEW_STRUCT 0xfe enum TYPE { - TYPE_NIL = 0x01, - TYPE_TREE = 0x02, - TYPE_REF = 0x03, - TYPE_PTR = 0x04, - TYPE_ITER = 0x05 + TYPE_NIL = 0x01, + TYPE_TREE = 0x02, + TYPE_REF = 0x03, + TYPE_PTR = 0x04, + TYPE_ITER = 0x05, + TYPE_STRUCT = 0x06, }; /* Types of Generics. */ diff --git a/src/colm.lm b/src/colm.lm index d2c8e3c7..e50b65f7 100644 --- a/src/colm.lm +++ b/src/colm.lm @@ -562,6 +562,7 @@ def code_factor | [MAKE_TOKEN POPEN call_arg_list PCLOSE] :MakeToken | [TYPEID LT type_ref GT] :TypeId | [NEW type_ref] :New +| [NEW2 type_ref] :New2 | [CAST LT type_ref GT code_factor] :Cast | [DEREF code_factor] :Deref diff --git a/src/compiler.cc b/src/compiler.cc index bf5deaa4..2378f3dd 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -743,11 +743,13 @@ LangEl *Compiler::makeRepeatProd( const InputLoc &loc, Namespace *nspace, /* Build the first production of the repeat. */ TypeRef *typeRef1 = TypeRef::cons( loc, ut ); - ProdEl *factor1 = new ProdEl( ProdEl::ReferenceType, InputLoc(), 0, false, typeRef1, 0 ); + ProdEl *factor1 = new ProdEl( ProdEl::ReferenceType, + InputLoc(), 0, false, typeRef1, 0 ); UniqueType *prodNameUT = findUniqueType( TYPE_TREE, prodName ); TypeRef *typeRef2 = TypeRef::cons( loc, prodNameUT ); - ProdEl *factor2 = new ProdEl( ProdEl::ReferenceType, InputLoc(), 0, false, typeRef2, 0 ); + ProdEl *factor2 = new ProdEl( ProdEl::ReferenceType, + InputLoc(), 0, false, typeRef2, 0 ); prodElList1->append( factor1 ); prodElList1->append( factor2 ); @@ -1126,6 +1128,7 @@ void Compiler::compile() prepGrammar(); placeAllLanguageObjects(); + placeAllStructObjects(); placeAllFrameObjects(); placeAllFunctions(); diff --git a/src/compiler.h b/src/compiler.h index bd92a049..0f9ff06c 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -541,6 +541,7 @@ struct Compiler void placeFrameFields( ObjectDef *localFrame ); void placeUserFunction( Function *func, bool isUserIter ); + void placeAllStructObjects(); void placeAllLanguageObjects(); void placeAllFrameObjects(); void placeAllFunctions(); @@ -821,6 +822,7 @@ struct Compiler */ LelList langEls; + StructElList structEls; DefList prodList; /* Dumping. */ @@ -881,6 +883,7 @@ struct Compiler UniqueType *findUniqueType( enum TYPE typeId ); UniqueType *findUniqueType( enum TYPE typeId, LangEl *langEl ); UniqueType *findUniqueType( enum TYPE typeId, IterDef *iterDef ); + UniqueType *findUniqueType( enum TYPE typeId, StructEl *structEl ); UniqueType *uniqueTypeNil; UniqueType *uniqueTypeVoid; @@ -1004,7 +1007,7 @@ typedef AvlMapEl<String, ColmParser *> ParserDictEl; LangEl *declareLangEl( Compiler *pd, Namespace *nspace, const String &data, LangEl::Type type ); -LangEl *declareStruct( Compiler *pd, Namespace *nspace, +LangEl *declareContext( Compiler *pd, Namespace *nspace, const String &data, LangEl::Type type ); LangEl *addLangEl( Compiler *pd, Namespace *nspace, const String &data, LangEl::Type type ); diff --git a/src/declare.cc b/src/declare.cc index bc9c59c5..926cecf3 100644 --- a/src/declare.cc +++ b/src/declare.cc @@ -164,7 +164,7 @@ LangEl *declareLangEl( Compiler *pd, Namespace *nspace, return langEl; } -LangEl *declareStruct( Compiler *pd, Namespace *nspace, +LangEl *declareContext( Compiler *pd, Namespace *nspace, const String &data, LangEl::Type type ) { /* If the id is already in the dict, it will be placed in last found. If @@ -175,13 +175,30 @@ LangEl *declareStruct( Compiler *pd, Namespace *nspace, /* Language element not there. Make the new lang el and insert.. */ LangEl *langEl = new LangEl( nspace, data, type ); - TypeMapEl *typeMapEl = new TypeMapEl( TypeMapEl::StructType, data, langEl ); - nspace->typeMap.insert( typeMapEl ); pd->langEls.append( langEl ); + TypeMapEl *typeMapEl = new TypeMapEl( TypeMapEl::ContextType, data, langEl ); + nspace->typeMap.insert( typeMapEl ); + return langEl; } +StructEl *declareStruct( Compiler *pd, Namespace *nspace, + const String &data, Context *context ) +{ + TypeMapEl *inDict = nspace->typeMap.find( data ); + if ( inDict != 0 ) + error() << "'" << data << "' already defined as something else" << endp; + + StructEl *structEl = new StructEl( nspace, data ); + pd->structEls.append( structEl ); + + TypeMapEl *typeMapEl = new TypeMapEl( TypeMapEl::StructType, data, structEl ); + nspace->typeMap.insert( typeMapEl ); + + return structEl; +} + /* Does not map the new language element. */ LangEl *addLangEl( Compiler *pd, Namespace *nspace, const String &data, LangEl::Type type ) @@ -372,7 +389,7 @@ void Namespace::declare( Compiler *pd ) } for ( ContextDefList::Iter c = contextDefList; c.lte(); c++ ) { - LangEl *lel = declareStruct( pd, this, c->name, LangEl::NonTerm ); + LangEl *lel = declareContext( pd, this, c->name, LangEl::NonTerm ); ProdElList *emptyList = new ProdElList; //addProduction( c->context->loc, c->name, emptyList, false, 0, 0 ); @@ -394,7 +411,7 @@ void Namespace::declare( Compiler *pd ) /* Insert the name into the top of the region stack after popping the * region just created. We need it in the parent. */ TypeMapEl *typeMapEl = new TypeMapEl( - TypeMapEl::StructType, c->name, prodName ); + TypeMapEl::ContextType, c->name, prodName ); this->parentNamespace->typeMap.insert( typeMapEl ); } } @@ -404,6 +421,21 @@ void Namespace::declare( Compiler *pd ) lel->objectDef = c->context->objectDef; } + for ( StructDefList::Iter c = structDefList; c.lte(); c++ ) { + StructEl *sel = declareStruct( pd, this, c->name, c->context ); + sel->context = c->context; + + /* If the token has the same name as the region it is in, then also + * insert it into the symbol map for the parent region. */ + if ( strcmp( c->name, this->name ) == 0 ) { + /* Insert the name into the top of the region stack after popping the + * region just created. We need it in the parent. */ + TypeMapEl *typeMapEl = new TypeMapEl( + TypeMapEl::StructType, c->name, sel ); + this->parentNamespace->typeMap.insert( typeMapEl ); + } + } + for ( TokenDefListNs::Iter tokenDef = tokenDefList; tokenDef.lte(); tokenDef++ ) { /* Literals already taken care of. */ if ( ! tokenDef->isLiteral ) { diff --git a/src/loadcolm.cc b/src/loadcolm.cc index fab197bf..50252cf7 100644 --- a/src/loadcolm.cc +++ b/src/loadcolm.cc @@ -1841,6 +1841,13 @@ struct LoadColm LangTerm::NewType, typeRef ) ); break; } + case code_factor::New2: { + TypeRef *typeRef = walkTypeRef( codeFactor.type_ref() ); + + expr = LangExpr::cons( LangTerm::cons( codeFactor.loc(), + LangTerm::New2Type, typeRef ) ); + break; + } case code_factor::Cast: { TypeRef *typeRef = walkTypeRef( codeFactor.type_ref() ); LangExpr *castExpr = walkCodeFactor( codeFactor._code_factor() ); @@ -2080,7 +2087,6 @@ struct LoadColm void walkContextVarDef( context_var_def ContextVarDef ) { ObjectDef *contextObj = curContext()->objectDef; - ObjectField::Type type = contextObj->type == ObjectDef::StructType ? ObjectField::StructFieldType : ObjectField::UserFieldType; @@ -2249,11 +2255,14 @@ struct LoadColm void walkContextDef( context_def contextDef ) { - ObjectDef::Type objectType = contextDef.struct_key().STRUCT() ? - ObjectDef::StructType : ObjectDef::UserType; - - String name = contextDef.id().data(); - contextHead( contextDef.id().loc(), name, objectType ); + if ( contextDef.struct_key().STRUCT() ) { + String name = contextDef.id().data(); + structHead( contextDef.id().loc(), name, ObjectDef::StructType ); + } + else { + String name = contextDef.id().data(); + contextHead( contextDef.id().loc(), name, ObjectDef::UserType ); + } _repeat_context_item contextItemList = contextDef.ItemList(); while ( !contextItemList.end() ) { diff --git a/src/lookup.cc b/src/lookup.cc index e044dbeb..354f497d 100644 --- a/src/lookup.cc +++ b/src/lookup.cc @@ -14,12 +14,15 @@ using std::endl; ObjectDef *UniqueType::objectDef() { - if ( typeId != TYPE_TREE && typeId != TYPE_REF ) { - /* This should have generated a compiler error. */ - assert(false); + if ( typeId == TYPE_TREE || typeId == TYPE_REF ) { + return langEl->objectDef; + } + else if ( typeId == TYPE_STRUCT ) { + return structEl->context->objectDef; } - return langEl->objectDef; + /* This should have generated a compiler error. */ + assert( false ); } /* Recurisve find through a single object def's scope. */ diff --git a/src/parser.cc b/src/parser.cc index 264508cd..b7892480 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -885,6 +885,22 @@ void BaseParser::contextHead( const InputLoc &loc, const String &data, data, pd->nextObjectId++ ); } +void BaseParser::structHead( const InputLoc &loc, const String &data, + ObjectDef::Type objectType ) +{ + /* Make the new namespace. */ + Namespace *nspace = createNamespace( loc, data ); + + Context *context = new Context( loc, 0 ); + contextStack.push( context ); + + StructDef *structDef = new StructDef( data, context, nspace ); + nspace->structDefList.append( structDef ); + + context->objectDef = ObjectDef::cons( objectType, + data, pd->nextObjectId++ ); +} + StmtList *BaseParser::appendStatement( StmtList *stmtList, LangStmt *stmt ) { if ( stmt != 0 ) diff --git a/src/parser.h b/src/parser.h index 088f7bc5..2a0134a6 100644 --- a/src/parser.h +++ b/src/parser.h @@ -116,6 +116,7 @@ struct BaseParser LangExpr *require( const InputLoc &loc, LangVarRef *varRef, PatternItemList *list ); void contextVarDef( const InputLoc &loc, ObjectField *objField ); void contextHead( const InputLoc &loc, const String &data, ObjectDef::Type objectType ); + void structHead( const InputLoc &loc, const String &data, ObjectDef::Type objectType ); StmtList *appendStatement( StmtList *stmtList, LangStmt *stmt ); ParameterList *appendParam( ParameterList *paramList, ObjectField *objField ); ObjectField *addParam( const InputLoc &loc, diff --git a/src/parsetree.cc b/src/parsetree.cc index 9f24d836..d514ea47 100644 --- a/src/parsetree.cc +++ b/src/parsetree.cc @@ -107,6 +107,12 @@ int CmpUniqueType::compare( const UniqueType &ut1, const UniqueType &ut2 ) } case TYPE_NIL: break; + case TYPE_STRUCT: + if ( ut1.structEl < ut2.structEl ) + return -1; + else if ( ut1.structEl > ut2.structEl ) + return 1; + break; } return 0; diff --git a/src/parsetree.h b/src/parsetree.h index 191e97af..a59d4a99 100644 --- a/src/parsetree.h +++ b/src/parsetree.h @@ -337,7 +337,6 @@ struct ContextStack { return length() > 0 ? Vector<Context*>::top() : 0; } }; - struct Context { Context( const InputLoc &loc, LangEl *lel ) @@ -352,6 +351,19 @@ struct Context ObjectDef *objectDef; }; +struct Struct +{ + Struct( const InputLoc &loc, ObjectDef *objectDef ) + : + loc(loc), + objectDef(objectDef) + {} + + InputLoc loc; + ObjectDef *objectDef; +}; + + typedef Vector<ReCapture> ReCaptureVect; struct TokenDefPtr1 @@ -557,28 +569,61 @@ struct ContextDef struct ContextDefList : DList<ContextDef> {}; +struct StructEl +{ + StructEl( Namespace *nspace, const String &name ) + : nspace(nspace), name(name), context(0) {} + + Namespace *nspace; + String name; + Context *context; + + StructEl *prev, *next; +}; + +typedef DList<StructEl> StructElList; + +struct StructDef +{ + StructDef( const String &name, Context *context, Namespace *nspace ) + : name(name), context(context), nspace(nspace) {} + + String name; + Context *context; + Namespace *nspace; + + StructDef *prev, *next; +}; + +struct StructDefList : DList<StructDef> {}; + struct TypeMapEl : public AvlTreeEl<TypeMapEl> { enum Type { AliasType = 1, - StructType, - LangElType + ContextType, + LangElType, + StructType }; const String &getKey() { return key; } TypeMapEl( Type type, const String &key, TypeRef *typeRef ) - : type(type), key(key), value(0), typeRef(typeRef) {} + : type(type), key(key), value(0), typeRef(typeRef), structEl(0) {} TypeMapEl( Type type, const String &key, LangEl *value ) - : type(type), key(key), value(value), typeRef(0) {} + : type(type), key(key), value(value), typeRef(0), structEl(0) {} + + TypeMapEl( Type type, const String &key, StructEl *structEl ) + : type(type), key(key), value(0), typeRef(0), structEl(structEl) {} Type type; String key; LangEl *value; TypeRef *typeRef; + StructEl *structEl; TypeMapEl *prev, *next; }; @@ -801,8 +846,8 @@ struct Namespace /* List of nonterminal defs in the namespace. */ NtDefList ntDefList; - /* List of context definitions for encapsulating the data of a parser. */ ContextDefList contextDefList; + StructDefList structDefList; /* Dictionary of symbols within the region. */ TypeMap typeMap; @@ -1795,24 +1840,35 @@ struct UniqueType : public AvlTreeEl<UniqueType> UniqueType( enum TYPE typeId ) : typeId(typeId), langEl(0), - iterDef(0) + iterDef(0), + structEl(0) {} UniqueType( enum TYPE typeId, LangEl *langEl ) : typeId(typeId), langEl(langEl), - iterDef(0) + iterDef(0), + structEl(0) {} UniqueType( enum TYPE typeId, IterDef *iterDef ) : typeId(typeId), langEl(0), - iterDef(iterDef) + iterDef(iterDef), + structEl(0) + {} + + UniqueType( enum TYPE typeId, StructEl *structEl ) : + typeId(typeId), + langEl(0), + iterDef(0), + structEl(structEl) {} enum TYPE typeId; LangEl *langEl; IterDef *iterDef; + StructEl *structEl; ObjectDef *objectDef(); }; @@ -2530,7 +2586,6 @@ struct ObjectDef long nextOffset; long firstNonTree; - void referenceField( Compiler *pd, ObjectField *field ); void placeField( Compiler *pd, ObjectField *field ); void createCode( Compiler *pd, CodeVect &code ); @@ -2709,6 +2764,7 @@ struct LangTerm StringType, MatchType, NewType, + New2Type, ConstructType, TypeIdType, SearchType, @@ -2911,6 +2967,7 @@ struct LangTerm void resolve( Compiler *pd ); UniqueType *evaluateNew( Compiler *pd, CodeVect &code ) const; + UniqueType *evaluateNew2( Compiler *pd, CodeVect &code ) const; UniqueType *evaluateConstruct( Compiler *pd, CodeVect &code ) const; UniqueType *evaluateNewstruct( Compiler *pd, CodeVect &code ) const; void parseFrag( Compiler *pd, CodeVect &code, int stopId ) const; diff --git a/src/program.h b/src/program.h index 0e6fbb9f..130a6532 100644 --- a/src/program.h +++ b/src/program.h @@ -80,6 +80,10 @@ typedef struct colm_sections } RuntimeData; +typedef struct colm_heap_item +{ + struct colm_heap_item *prev, *next; +} HeapItem; typedef struct colm_program { @@ -107,6 +111,8 @@ typedef struct colm_program Kid *heap; + struct colm_heap_item *heapHead, *heapTail; + Stream *stdinVal; Stream *stdoutVal; Stream *stderrVal; diff --git a/src/resolve.cc b/src/resolve.cc index 7b16ca96..cb97ccf4 100644 --- a/src/resolve.cc +++ b/src/resolve.cc @@ -46,7 +46,7 @@ UniqueType *TypeRef::resolveTypeName( Compiler *pd ) return inDict->typeRef->resolveType( pd ); } - case TypeMapEl::StructType: { + case TypeMapEl::ContextType: { UniqueType *structUt = pd->findUniqueType( TYPE_TREE, inDict->value ); return pd->findUniqueType( TYPE_PTR, structUt->langEl ); } @@ -57,6 +57,10 @@ UniqueType *TypeRef::resolveTypeName( Compiler *pd ) return pd->findUniqueType( TYPE_PTR, ut->langEl ); return ut; } + case TypeMapEl::StructType: { + UniqueType *ut = pd->findUniqueType( TYPE_STRUCT, inDict->structEl ); + return ut; + } } } @@ -576,6 +580,9 @@ void LangTerm::resolve( Compiler *pd ) case NewType: typeRef->resolveType( pd ); break; + case New2Type: + typeRef->resolveType( pd ); + break; case TypeIdType: typeRef->resolveType( pd ); break; @@ -839,11 +846,16 @@ void Compiler::resolveParseTree() } } + for ( StructElList::Iter sel = structEls; sel.lte(); sel++ ) { + ObjectDef *objDef = sel->context->objectDef; + for ( FieldList::Iter f = *objDef->fieldList; f.lte(); f++ ) + f->value->typeRef->resolveType( this ); + } + /* Init all fields of the global object. */ for ( FieldList::Iter f = *globalObjectDef->fieldList; f.lte(); f++ ) { f->value->typeRef->resolveType( this ); } - } /* Resolves production els and computes the precedence of each prod. */ diff --git a/src/synthesis.cc b/src/synthesis.cc index d362d745..fc5245b9 100644 --- a/src/synthesis.cc +++ b/src/synthesis.cc @@ -182,6 +182,17 @@ UniqueType *Compiler::findUniqueType( enum TYPE typeId, IterDef *iterDef ) return uniqueType; } +UniqueType *Compiler::findUniqueType( enum TYPE typeId, StructEl *structEl ) +{ + UniqueType searchKey( typeId, structEl ); + UniqueType *uniqueType = uniqeTypeMap.find( &searchKey ); + if ( uniqueType == 0 ) { + uniqueType = new UniqueType( typeId, structEl ); + uniqeTypeMap.insert( uniqueType ); + } + return uniqueType; +} + /* 0-based. */ ObjectField *ObjectDef::findFieldNum( long offset ) { @@ -264,9 +275,14 @@ UniqueType *LangVarRef::loadField( Compiler *pd, CodeVect &code, } if ( el->useOffset() ) { - /* Gets of locals and fields require offsets. Fake vars like token - * data and lhs don't require it. */ - code.appendHalf( el->offset ); + if ( elUT->typeId == TYPE_STRUCT ) { + code.appendHalf( -el->offset + 64 ); + } + else { + /* Gets of locals and fields require offsets. Fake vars like token + * data and lhs don't require it. */ + code.appendHalf( el->offset ); + } } else if ( el->isRhsGet() ) { /* Need to place the array computing the val. */ @@ -404,6 +420,9 @@ void LangVarRef::loadQualification( Compiler *pd, CodeVect &code, qualUT = pd->findUniqueType( TYPE_TREE, qualUT->langEl ); } + else if ( qualUT->typeId == TYPE_STRUCT ) { + + } else { error(loc) << "arrow operator cannot be used to access this type" << endp; } @@ -551,8 +570,12 @@ void LangVarRef::setField( Compiler *pd, CodeVect &code, code.append( el->inSetWC ); /* Maybe write out an offset. */ - if ( el->useOffset() ) - code.appendHalf( el->offset ); + if ( el->useOffset() ) { + if ( exprUT->typeId == TYPE_STRUCT ) + code.appendHalf( -el->offset + 64 ); + else + code.appendHalf( el->offset ); + } } @@ -1027,6 +1050,19 @@ UniqueType *LangTerm::evaluateNew( Compiler *pd, CodeVect &code ) const return pd->findUniqueType( TYPE_PTR, ut->langEl ); } +UniqueType *LangTerm::evaluateNew2( Compiler *pd, CodeVect &code ) const +{ + /* What is being newstructed. */ + UniqueType *replUT = typeRef->uniqueType; + + if ( replUT->typeId != TYPE_STRUCT ) + error(loc) << "can only new2 a struct" << endp; + + code.append( IN_NEW_STRUCT ); + code.appendHalf( replUT->structEl->context->objectDef->size() ); + return replUT; +} + UniqueType *LangTerm::evaluateCast( Compiler *pd, CodeVect &code ) const { expr->evaluate( pd, code ); @@ -1125,6 +1161,9 @@ UniqueType *LangTerm::evaluateNewstruct( Compiler *pd, CodeVect &code ) const /* What is being newstructed. */ UniqueType *replUT = typeRef->uniqueType; + if ( replUT->typeId == TYPE_STRUCT ) + error(loc) << "cannot new a struct, use new2" << endp; + if ( replUT->langEl->generic != 0 ) { /* Use the new generic. */ code.append( IN_CONS_GENERIC ); @@ -1692,6 +1731,8 @@ UniqueType *LangTerm::evaluate( Compiler *pd, CodeVect &code ) const return evaluateSendTree( pd, code ); case NewType: return evaluateNew( pd, code ); + case New2Type: + return evaluateNew2( pd, code ); case TypeIdType: { /* Evaluate the expression. */ UniqueType *ut = typeRef->uniqueType; @@ -2716,6 +2757,15 @@ void Compiler::placeAllLanguageObjects() globalObjectDef->placeField( this, f->value ); } +void Compiler::placeAllStructObjects() +{ + for ( StructElList::Iter s = structEls; s.lte(); s++ ) { + ObjectDef *objectDef = s->context->objectDef; + for ( FieldList::Iter f = *objectDef->fieldList; f.lte(); f++ ) + objectDef->placeField( this, f->value ); + } +} + void Compiler::placeFrameFields( ObjectDef *localFrame ) { for ( FieldList::Iter f = *localFrame->fieldList; f.lte(); f++ ) @@ -253,6 +253,24 @@ Tree *constructPointer( Program *prg, Tree *tree ) return (Tree*)pointer; } +HeapItem *newStruct( Program *prg, int size ) +{ + HeapItem *hi = (HeapItem*) malloc( sizeof(Tree*) * ( 2 + size ) ); + + if ( prg->heapHead == 0 ) { + prg->heapHead = prg->heapTail = hi; + hi->prev = hi->next = 0; + } + else { + hi->prev = prg->heapTail; + hi->next = 0; + prg->heapTail->next = hi; + prg->heapTail = hi; + } + + return hi; +} + Tree *constructTerm( Program *prg, Word id, Head *tokdata ) { LangElInfo *lelInfo = prg->rtd->lelInfo; @@ -360,6 +360,8 @@ void userIterDestroy2( struct colm_program *prg, Tree ***psp, UserIter *uiter ); Tree *castTree( struct colm_program *prg, int langElId, Tree *tree ); StreamImpl *streamToImpl( Stream *ptr ); +struct colm_heap_item *newStruct( struct colm_program *prg, int size ); + #if defined(__cplusplus) } #endif |