summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2014-12-19 20:23:04 -0500
committerAdrian Thurston <thurston@complang.org>2014-12-19 20:23:04 -0500
commitdb9cfbc7d06ed34f1fe73465d81d3ac0975adaff (patch)
tree406d44a974f7242787b3c632146511785391f325 /src
parent12495ae402a5c9d80d467d9baae72f91ebac13cb (diff)
downloadcolm-db9cfbc7d06ed34f1fe73465d81d3ac0975adaff.tar.gz
hacked together some struct (non-tree) semantics
Can new, get and set non-tree objects (very limited features).
Diffstat (limited to 'src')
-rw-r--r--src/bytecode.c53
-rw-r--r--src/bytecode.h12
-rw-r--r--src/colm.lm1
-rw-r--r--src/compiler.cc7
-rw-r--r--src/compiler.h5
-rw-r--r--src/declare.cc42
-rw-r--r--src/loadcolm.cc21
-rw-r--r--src/lookup.cc11
-rw-r--r--src/parser.cc16
-rw-r--r--src/parser.h1
-rw-r--r--src/parsetree.cc6
-rw-r--r--src/parsetree.h77
-rw-r--r--src/program.h6
-rw-r--r--src/resolve.cc16
-rw-r--r--src/synthesis.cc60
-rw-r--r--src/tree.c18
-rw-r--r--src/tree.h2
17 files changed, 298 insertions, 56 deletions
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++ )
diff --git a/src/tree.c b/src/tree.c
index e50dd233..5984a204 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -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;
diff --git a/src/tree.h b/src/tree.h
index 148d52e3..4f6447ab 100644
--- a/src/tree.h
+++ b/src/tree.h
@@ -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