File Annotation
Not logged in
8de5b49cdf 2010-11-09        kinaba: /**
b0d8d7875b 2010-11-08        kinaba:  * Authors: k.inaba
b0d8d7875b 2010-11-08        kinaba:  * License: NYSL 0.9982 http://www.kmonos.net/nysl/
b0d8d7875b 2010-11-08        kinaba:  *
b0d8d7875b 2010-11-08        kinaba:  * Runtime data structures for Polemy programming language.
b0d8d7875b 2010-11-08        kinaba:  */
b0d8d7875b 2010-11-08        kinaba: module polemy.value;
b0d8d7875b 2010-11-08        kinaba: import polemy._common;
3464a035ec 2010-11-20        kinaba: import polemy.failure;
3f6f41b558 2010-11-20        kinaba: import polemy.ast;
435fa085ec 2010-11-21        kinaba: import polemy.layer;
b0d8d7875b 2010-11-08        kinaba: 
aa770610d3 2010-11-08        kinaba: /// Runtime values of Polemy
b0d8d7875b 2010-11-08        kinaba: 
b0d8d7875b 2010-11-08        kinaba: abstract class Value
b0d8d7875b 2010-11-08        kinaba: {
b97bd4f713 2010-11-23        kinaba: 	override bool opEquals(Object rhs) { return 0==opCmp(rhs); }
b0d8d7875b 2010-11-08        kinaba: }
b0d8d7875b 2010-11-08        kinaba: 
515502e8d1 2010-11-20        kinaba: ///
b0d8d7875b 2010-11-08        kinaba: class IntValue : Value
b0d8d7875b 2010-11-08        kinaba: {
b0d8d7875b 2010-11-08        kinaba: 	BigInt data;
aa770610d3 2010-11-08        kinaba: 
36c517dfc4 2010-11-23        kinaba: 	this(bool n) { this.data = n?1:0; }
b97bd4f713 2010-11-23        kinaba: 	this(int n) { this.data = n; }
b97bd4f713 2010-11-23        kinaba: 	this(long n) { this.data = n; }
b97bd4f713 2010-11-23        kinaba: 	this(BigInt n) { this.data = n; }
b97bd4f713 2010-11-23        kinaba: 	this(string n) { this.data = BigInt(n); }
b97bd4f713 2010-11-23        kinaba: 	override string toString() const { return toDecimalString(cast(BigInt)data); }
b97bd4f713 2010-11-23        kinaba: 	override int opCmp(Object rhs) {
b97bd4f713 2010-11-23        kinaba: 		if(auto r = cast(IntValue)rhs) return data.opCmp(r.data);
b97bd4f713 2010-11-23        kinaba: 		if(auto r = cast(Value)rhs)    return typeid(this).opCmp(typeid(r));
b97bd4f713 2010-11-23        kinaba: 		throw genex!RuntimeException(LexPosition.dummy, "comparison with value and somithing other");
b97bd4f713 2010-11-23        kinaba: 	}
b97bd4f713 2010-11-23        kinaba: 	mixin SimpleToHash;
b0d8d7875b 2010-11-08        kinaba: }
b0d8d7875b 2010-11-08        kinaba: 
515502e8d1 2010-11-20        kinaba: ///
b0d8d7875b 2010-11-08        kinaba: class StrValue : Value
b0d8d7875b 2010-11-08        kinaba: {
b0d8d7875b 2010-11-08        kinaba: 	string data;
aa770610d3 2010-11-08        kinaba: 
b97bd4f713 2010-11-23        kinaba: 	mixin SimpleConstructor;
b0d8d7875b 2010-11-08        kinaba: 	override string toString() const { return data; }
b97bd4f713 2010-11-23        kinaba: 	override int opCmp(Object rhs) {
b97bd4f713 2010-11-23        kinaba: 		if(auto r = cast(StrValue)rhs) return typeid(string).compare(&data, &r.data);
b97bd4f713 2010-11-23        kinaba: 		if(auto r = cast(Value)rhs)    return typeid(this).opCmp(typeid(r));
b97bd4f713 2010-11-23        kinaba: 		throw genex!RuntimeException(LexPosition.dummy, "comparison with value and somithing other");
b97bd4f713 2010-11-23        kinaba: 	}
b97bd4f713 2010-11-23        kinaba: 	mixin SimpleToHash;
b0d8d7875b 2010-11-08        kinaba: }
b0d8d7875b 2010-11-08        kinaba: 
515502e8d1 2010-11-20        kinaba: ///
b97bd4f713 2010-11-23        kinaba: class UndefinedValue : Value
b0d8d7875b 2010-11-08        kinaba: {
b97bd4f713 2010-11-23        kinaba: 	mixin SimpleConstructor;
a5fe6233c1 2010-11-21        kinaba: 	override string toString() const { return "<undefined>"; }
b97bd4f713 2010-11-23        kinaba: 	override int opCmp(Object rhs) {
b97bd4f713 2010-11-23        kinaba: 		if(auto r = cast(StrValue)rhs) return 0;
b97bd4f713 2010-11-23        kinaba: 		if(auto r = cast(Value)rhs)    return typeid(this).opCmp(typeid(r));
b97bd4f713 2010-11-23        kinaba: 		throw genex!RuntimeException(LexPosition.dummy, "comparison with value and somithing other");
b97bd4f713 2010-11-23        kinaba: 	}
b97bd4f713 2010-11-23        kinaba: 	mixin SimpleToHash;
aa770610d3 2010-11-08        kinaba: }
aa770610d3 2010-11-08        kinaba: 
515502e8d1 2010-11-20        kinaba: ///
a5fe6233c1 2010-11-21        kinaba: abstract class FunValue : Value
5afe8e3f26 2010-11-13        kinaba: {
a5fe6233c1 2010-11-21        kinaba: 	const(Parameter[]) params();
a5fe6233c1 2010-11-21        kinaba: 	Table definitionContext();
b97bd4f713 2010-11-23        kinaba: 	Value invoke(Layer lay, Table ctx, LexPosition pos);
5afe8e3f26 2010-11-13        kinaba: }
aa770610d3 2010-11-08        kinaba: 
aa770610d3 2010-11-08        kinaba: /// Context (variable environment)
aa770610d3 2010-11-08        kinaba: /// Simlar to prototype chain of ECMAScript etc.
aa770610d3 2010-11-08        kinaba: /// But extended with the notion of "Layer"
aa770610d3 2010-11-08        kinaba: 
aa770610d3 2010-11-08        kinaba: class Table : Value
b0d8d7875b 2010-11-08        kinaba: {
aa770610d3 2010-11-08        kinaba: 	enum Kind {PropagateSet, NotPropagateSet};
a5fe6233c1 2010-11-21        kinaba: 	bool kill = false; // to refactor
aa770610d3 2010-11-08        kinaba: 
aa770610d3 2010-11-08        kinaba: 	this( Table proto=null, Kind k = Kind.PropagateSet )
aa770610d3 2010-11-08        kinaba: 		{ this.prototype = proto; this.kind = k; }
aa770610d3 2010-11-08        kinaba: 
6ac127ddd0 2010-11-23        kinaba: 	void set(string i, Layer lay, Value v, LexPosition pos=null)
8de5b49cdf 2010-11-09        kinaba: 	{
8de5b49cdf 2010-11-09        kinaba: 		if( setIfExist(i, lay, v) )
8de5b49cdf 2010-11-09        kinaba: 			return;
8de5b49cdf 2010-11-09        kinaba: 		data[i][lay] = v;
8de5b49cdf 2010-11-09        kinaba: 	}
8de5b49cdf 2010-11-09        kinaba: 
6ac127ddd0 2010-11-23        kinaba: 	bool has(string i, Layer lay) const
515502e8d1 2010-11-20        kinaba: 	{
515502e8d1 2010-11-20        kinaba: 		if( i in data ) {
515502e8d1 2010-11-20        kinaba: 			if( lay !in data[i] )
a5fe6233c1 2010-11-21        kinaba: 				return false;
a5fe6233c1 2010-11-21        kinaba: 			if(kill)
515502e8d1 2010-11-20        kinaba: 				return false;
515502e8d1 2010-11-20        kinaba: 			return true;
515502e8d1 2010-11-20        kinaba: 		}
515502e8d1 2010-11-20        kinaba: 		if( prototype is null )
515502e8d1 2010-11-20        kinaba: 			return false;
6ac127ddd0 2010-11-23        kinaba: 		return prototype.has(i, lay);
515502e8d1 2010-11-20        kinaba: 	}
515502e8d1 2010-11-20        kinaba: 
6ac127ddd0 2010-11-23        kinaba: 	Value get(string i, Layer lay, LexPosition pos=null)
aa770610d3 2010-11-08        kinaba: 	{
5afe8e3f26 2010-11-13        kinaba: 		if( i in data ) {
515502e8d1 2010-11-20        kinaba: 			// [TODO] consider forwarding to proto also in this case
5afe8e3f26 2010-11-13        kinaba: 			if( lay !in data[i] )
f86026acb8 2010-11-21        kinaba: 				throw genex!RuntimeException(pos, sprintf!"'%s' is not set in layer %s"(i,lay));
a5fe6233c1 2010-11-21        kinaba: 			if(kill)
f86026acb8 2010-11-21        kinaba: 				throw genex!RuntimeException(pos, sprintf!"'%s' is killed in macro"(i));
aa770610d3 2010-11-08        kinaba: 			return data[i][lay];
5afe8e3f26 2010-11-13        kinaba: 		}
aa770610d3 2010-11-08        kinaba: 		if( prototype is null )
f86026acb8 2010-11-21        kinaba: 			throw new RuntimeException(pos, sprintf!"'%s' not found"(i));
5afe8e3f26 2010-11-13        kinaba: 		return prototype.get(i, lay, pos);
3f6f41b558 2010-11-20        kinaba: 	}
3f6f41b558 2010-11-20        kinaba: 
3f6f41b558 2010-11-20        kinaba: 	T access(T,S...)( Layer lay, string path, S rest )
3f6f41b558 2010-11-20        kinaba: 	{
3f6f41b558 2010-11-20        kinaba: 		static if( rest.length == 0 )
3f6f41b558 2010-11-20        kinaba: 		{
3f6f41b558 2010-11-20        kinaba: 			if( this.has(path, lay) )
3f6f41b558 2010-11-20        kinaba: 				return cast(T) this.get(path, lay);
3f6f41b558 2010-11-20        kinaba: 		}
3f6f41b558 2010-11-20        kinaba: 		else
3f6f41b558 2010-11-20        kinaba: 		{
3f6f41b558 2010-11-20        kinaba: 			if(auto next = this.access!Table(lay,path))
3f6f41b558 2010-11-20        kinaba: 				return next.access!T(lay,rest);
3f6f41b558 2010-11-20        kinaba: 		}
3f6f41b558 2010-11-20        kinaba: 		return null;
8e3db9ef20 2010-11-20        kinaba: 	}
8e3db9ef20 2010-11-20        kinaba: 
8e3db9ef20 2010-11-20        kinaba: 	string toStringWithoutParen() const
8e3db9ef20 2010-11-20        kinaba: 	{
8e3db9ef20 2010-11-20        kinaba: 		string result;
8e3db9ef20 2010-11-20        kinaba: 		bool first = true;
8e3db9ef20 2010-11-20        kinaba: 		foreach(k, l2d; data)
8e3db9ef20 2010-11-20        kinaba: 			foreach(l,d; l2d)
8e3db9ef20 2010-11-20        kinaba: 			{
8e3db9ef20 2010-11-20        kinaba: 				if(first) first=false; else result~=", ";
8e3db9ef20 2010-11-20        kinaba: 				result ~= k;
6ac127ddd0 2010-11-23        kinaba: 				if( l.empty )
6ac127ddd0 2010-11-23        kinaba: 					result ~= "(emptylayer)";
6ac127ddd0 2010-11-23        kinaba: 				else if( l != ValueLayer )
6ac127ddd0 2010-11-23        kinaba: 					result ~= l;
8e3db9ef20 2010-11-20        kinaba: 				result ~= ":";
8e3db9ef20 2010-11-20        kinaba: 				result ~= text(cast(Value)d);
8e3db9ef20 2010-11-20        kinaba: 			}
8e3db9ef20 2010-11-20        kinaba: 		if( prototype !is null )
8e3db9ef20 2010-11-20        kinaba: 		{
8e3db9ef20 2010-11-20        kinaba: 			result ~= " / ";
8e3db9ef20 2010-11-20        kinaba: 			result ~= prototype.toStringWithoutParen();
8e3db9ef20 2010-11-20        kinaba: 		}
8e3db9ef20 2010-11-20        kinaba: 		return result;
8e3db9ef20 2010-11-20        kinaba: 	}
8e3db9ef20 2010-11-20        kinaba: 
8e3db9ef20 2010-11-20        kinaba: 	string toString() const
8e3db9ef20 2010-11-20        kinaba: 	{
8e3db9ef20 2010-11-20        kinaba: 		return "{" ~ toStringWithoutParen() ~ "}";
b0d8d7875b 2010-11-08        kinaba: 	}
b0d8d7875b 2010-11-08        kinaba: 
aa770610d3 2010-11-08        kinaba: private:
aa770610d3 2010-11-08        kinaba: 	Table                prototype;
aa770610d3 2010-11-08        kinaba: 	Kind                 kind;
aa770610d3 2010-11-08        kinaba: 	Value[Layer][string] data;
aa770610d3 2010-11-08        kinaba: 
aa770610d3 2010-11-08        kinaba: 	bool setIfExist(string i, Layer lay, Value v)
b0d8d7875b 2010-11-08        kinaba: 	{
aa770610d3 2010-11-08        kinaba: 		if( i in data )
aa770610d3 2010-11-08        kinaba: 		{
aa770610d3 2010-11-08        kinaba: 			data[i][lay] = v;
aa770610d3 2010-11-08        kinaba: 			return true;
aa770610d3 2010-11-08        kinaba: 		}
aa770610d3 2010-11-08        kinaba: 		if( kind==Kind.PropagateSet && prototype !is null )
aa770610d3 2010-11-08        kinaba: 			return prototype.setIfExist(i, lay, v);
aa770610d3 2010-11-08        kinaba: 		return false;
b0d8d7875b 2010-11-08        kinaba: 	}
aa770610d3 2010-11-08        kinaba: }
aa770610d3 2010-11-08        kinaba: 
aa770610d3 2010-11-08        kinaba: unittest
aa770610d3 2010-11-08        kinaba: {
aa770610d3 2010-11-08        kinaba: 	Table c0 = new Table;
aa770610d3 2010-11-08        kinaba: 	Table c01 = new Table(c0, Table.Kind.NotPropagateSet);
aa770610d3 2010-11-08        kinaba: 	Table c012 = new Table(c01, Table.Kind.PropagateSet);
aa770610d3 2010-11-08        kinaba: 	Table c013 = new Table(c01, Table.Kind.PropagateSet);
aa770610d3 2010-11-08        kinaba: 
435fa085ec 2010-11-21        kinaba: 	assert_nothrow( c012.set("x", ValueLayer, new IntValue(BigInt(12))) );
435fa085ec 2010-11-21        kinaba: 	assert_throw!RuntimeException( c013.get("x", ValueLayer) );
435fa085ec 2010-11-21        kinaba: 	assert_nothrow( c013.set("x", ValueLayer, new IntValue(BigInt(13))) );
435fa085ec 2010-11-21        kinaba: 	assert_eq( c013.get("x", ValueLayer), new IntValue(BigInt(13)) );
435fa085ec 2010-11-21        kinaba: 	assert_eq( c012.get("x", ValueLayer), new IntValue(BigInt(12)) );
435fa085ec 2010-11-21        kinaba: 	assert_throw!RuntimeException( c01.get("x", ValueLayer) );
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba: 	assert_nothrow( c01.set("y", ValueLayer, new IntValue(BigInt(1))) );
435fa085ec 2010-11-21        kinaba: 	assert_eq( c013.get("y", ValueLayer), new IntValue(BigInt(1)) );
435fa085ec 2010-11-21        kinaba: 	assert_eq( c012.get("y", ValueLayer), new IntValue(BigInt(1)) );
435fa085ec 2010-11-21        kinaba: 	assert_eq( c01.get("y", ValueLayer), new IntValue(BigInt(1)) );
aa770610d3 2010-11-08        kinaba: 
435fa085ec 2010-11-21        kinaba: 	assert_nothrow( c0.set("z", ValueLayer, new IntValue(BigInt(0))) );
435fa085ec 2010-11-21        kinaba: 	assert_eq( c013.get("z", ValueLayer), new IntValue(BigInt(0)) );
435fa085ec 2010-11-21        kinaba: 	assert_eq( c012.get("z", ValueLayer), new IntValue(BigInt(0)) );
435fa085ec 2010-11-21        kinaba: 	assert_eq( c01.get("z", ValueLayer), new IntValue(BigInt(0)) );
435fa085ec 2010-11-21        kinaba: 	assert_eq( c0.get("z", ValueLayer), new IntValue(BigInt(0)) );
aa770610d3 2010-11-08        kinaba: 
435fa085ec 2010-11-21        kinaba: 	assert_nothrow( c012.set("y", ValueLayer, new IntValue(BigInt(444))) );
435fa085ec 2010-11-21        kinaba: 	assert_eq( c013.get("y", ValueLayer), new IntValue(BigInt(444)) );
435fa085ec 2010-11-21        kinaba: 	assert_eq( c012.get("y", ValueLayer), new IntValue(BigInt(444)) );
435fa085ec 2010-11-21        kinaba: 	assert_eq( c01.get("y", ValueLayer), new IntValue(BigInt(444)) );
aa770610d3 2010-11-08        kinaba: 
435fa085ec 2010-11-21        kinaba: 	assert_nothrow( c012.set("z", ValueLayer, new IntValue(BigInt(555))) );
435fa085ec 2010-11-21        kinaba: 	assert_eq( c013.get("z", ValueLayer), new IntValue(BigInt(0)) );
435fa085ec 2010-11-21        kinaba: 	assert_eq( c012.get("z", ValueLayer), new IntValue(BigInt(555)) );
435fa085ec 2010-11-21        kinaba: 	assert_eq( c01.get("z", ValueLayer), new IntValue(BigInt(0)) );
435fa085ec 2010-11-21        kinaba: 	assert_eq( c0.get("z", ValueLayer), new IntValue(BigInt(0)) );
b0d8d7875b 2010-11-08        kinaba: 
aa770610d3 2010-11-08        kinaba: 	// [TODO] define the semantics and test @layers
b0d8d7875b 2010-11-08        kinaba: }