소스 검색

added include(shader) to include definitions

Nicolas Cannasse 11 년 전
부모
커밋
223cb1bf33
2개의 변경된 파일46개의 추가작업 그리고 4개의 파일을 삭제
  1. 28 3
      hxsl/Checker.hx
  2. 18 1
      hxsl/Macros.hx

+ 28 - 3
hxsl/Checker.hx

@@ -117,6 +117,11 @@ class Checker {
 		return Ast.Error.t(msg,pos);
 	}
 
+	public dynamic function loadShader( path : String ) : Expr {
+		throw "Not implemented";
+		return null;
+	}
+
 	public function check( name : String, shader : Expr ) : ShaderData {
 		vars = new Map();
 		inLoop = false;
@@ -498,12 +503,14 @@ class Checker {
 		}
 	}
 
-	function checkExpr( e : Expr, funs : Array<{ f : FunDecl, p : Position }> ) {
+	function checkExpr( e : Expr, funs : Array<{ f : FunDecl, p : Position }>, isIncluded = false ) {
 		switch( e.expr ) {
 		case EBlock(el):
 			for( e in el )
-				checkExpr(e,funs);
+				checkExpr(e,funs, isIncluded);
 		case EFunction(f):
+			if( isIncluded )
+				return;
 			funs.push({ f : f, p : e.pos });
 		case EVars(vl):
 			for( v in vl ) {
@@ -519,8 +526,26 @@ class Checker {
 				if( v.expr != null ) error("Cannot initialize variable declaration", v.expr.pos);
 				if( v.type == null ) error("Type required for variable declaration", e.pos);
 				if( vars.exists(v.name) ) error("Duplicate var decl '" + v.name + "'", e.pos);
-				vars.set(v.name, makeVar(v, e.pos));
+				var v = makeVar(v, e.pos);
+				if( isIncluded && (v.kind == Param || v.kind == Var) )
+					continue;
+				vars.set(v.name, v);
+			}
+		case ECall( { expr : EIdent("include") }, [e]):
+			var path = [];
+			function loop( e : Expr ) {
+				switch( e.expr ) {
+				case EIdent(n): path.push(n);
+				case EField(e, f): loop(e); path.push(f);
+				default:
+					error("Should be a shader type path", e.pos);
+				}
 			}
+			loop(e);
+			var sexpr = null;
+			try sexpr = loadShader(path.join(".")) catch( err : Dynamic ) error(Std.string(err), e.pos);
+			if( sexpr != null )
+				checkExpr(sexpr, funs, true);
 		default:
 			error("This expression is not allowed at shader declaration level", e.pos);
 		}

+ 18 - 1
hxsl/Macros.hx

@@ -229,6 +229,20 @@ class Macros {
 		return fields;
 	}
 
+	static function loadShader( path : String ) {
+		var m = Context.follow(Context.getType(path));
+		switch( m ) {
+		case TInst(c, _):
+			var c = c.get();
+			for( m in c.meta.get() )
+				if( m.name == ":src" )
+					return new MacroParser().parseExpr(m.params[0]);
+		default:
+		}
+		throw path + " is not a shader";
+		return null;
+	}
+
 	public static function buildShader() {
 		var fields = Context.getBuildFields();
 		for( f in fields )
@@ -237,10 +251,13 @@ class Macros {
 				case FVar(_, expr) if( expr != null ):
 					var pos = expr.pos;
 					if( !Lambda.has(f.access, AStatic) ) f.access.push(AStatic);
+					Context.getLocalClass().get().meta.add(":src", [expr], pos);
 					try {
 						var shader = new MacroParser().parseExpr(expr);
 						var name = Std.string(Context.getLocalClass());
-						var shader = new Checker().check(name,shader);
+						var check = new Checker();
+						check.loadShader = loadShader;
+						var shader = check.check(name,shader);
 						var str = Serializer.run(shader);
 						f.kind = FVar(null, { expr : EConst(CString(str)), pos : pos } );
 						f.meta.push({