Nicolas Cannasse 14 лет назад
Родитель
Сommit
093f55ddf3

+ 1 - 0
doc/CHANGES.txt

@@ -9,6 +9,7 @@
 	macro : added ECheckType
 	macro : added TLazy for not-yet-typed class fields
 	js/php/neko : added haxe.web.Request
+	all : added Std.format
 
 2011-09-25: 2.08
 	js : added js.JQuery

+ 1 - 0
doc/ImportAll.hx

@@ -73,6 +73,7 @@ class ImportAll {
 					switch( cl ) {
 					case "ImportAll", "neko.db.MacroManager": continue;
 					case "haxe.TimerQueue": if( Context.defined("neko") || Context.defined("php") ) continue;
+					case "haxe.web.Request": if( !(Context.defined("neko") || Context.defined("php") || Context.defined("js")) ) continue;
 					case "haxe.macro.DefaultJSGenerator","haxe.macro.Context", "haxe.macro.Compiler": if( !Context.defined("neko") ) continue;
 					case "haxe.remoting.SocketWrapper": if( !Context.defined("flash") ) continue;
 					case "haxe.remoting.SyncSocketConnection": if( !(Context.defined("neko") || Context.defined("php") || Context.defined("cpp")) ) continue;

+ 3 - 0
std/Std.hx

@@ -62,4 +62,7 @@ extern class Std {
 	**/
 	public static function random( x : Int ) : Int;
 
+
+	@:macro public static function format( fmt : haxe.macro.Expr.ExprRequire<String> ) : haxe.macro.Expr.ExprRequire<String>;
+
 }

+ 4 - 0
std/cpp/_std/Std.hx

@@ -48,4 +48,8 @@
 		return untyped __global__.rand() % x;
 	}
 
+	@:macro public static function format( fmt : haxe.macro.Expr.ExprRequire<String> ) : haxe.macro.Expr.ExprRequire<String> {
+		return haxe.macro.Format.format(fmt);
+	}
+
 }

+ 4 - 0
std/flash/_std/Std.hx

@@ -57,6 +57,10 @@
 		return untyped __random__(x);
 	}
 
+	@:macro public static function format( fmt : haxe.macro.Expr.ExprRequire<String> ) : haxe.macro.Expr.ExprRequire<String> {
+		return haxe.macro.Format.format(fmt);
+	}
+
 	static function __init__() : Void untyped {
 		var g : Dynamic = _global;
 		g["Int"] = { __name__ : ["Int"] };

+ 4 - 0
std/flash9/_std/Std.hx

@@ -52,4 +52,8 @@
 		return untyped Math.floor(Math.random()*x);
 	}
 
+	@:macro public static function format( fmt : haxe.macro.Expr.ExprRequire<String> ) : haxe.macro.Expr.ExprRequire<String> {
+		return haxe.macro.Format.format(fmt);
+	}
+
 }

+ 112 - 0
std/haxe/macro/Format.hx

@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2005-2011, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+package haxe.macro;
+import haxe.macro.Expr;
+import haxe.macro.Context;
+
+/**
+	The actual macro implemented for Std.format
+**/
+class Format {
+
+	#if macro
+	public static function format( estr : Expr ) {
+		var str = switch( estr.expr ) {
+			case EConst(c): switch(c) { case CString(s): s; default: null; }
+			default: null;
+		};
+		if( str == null )
+			Context.error("Constant string required", estr.pos);
+		var pos = Context.getPosInfos(estr.pos);
+		var min = pos.min;
+		pos.min++;
+		var expr = null;
+		function make(size) {
+			pos.max = pos.min + size;
+			var p = Context.makePosition(pos);
+			pos.min += size;
+			return p;
+		}
+		function add(e) {
+			if( expr == null )
+				expr = e;
+			else
+				expr = { expr : EBinop(OpAdd,expr,e), pos : Context.makePosition({ min : min, max : pos.min, file : pos.file }) };
+		}
+		var i = 0, start = 0;
+		var max = str.length;
+		while( i < max ) {
+			if( StringTools.fastCodeAt(str,i++) != '$'.code )
+				continue;
+			var len = i - start - 1;
+			if( len > 0 || expr == null )
+				add({ expr : EConst(CString(str.substr(start,len))), pos : make(len) });
+			pos.min++;
+			start = i;
+			var c = StringTools.fastCodeAt(str, i);
+			if( c == '{'.code ) {
+				var count = 1;
+				i++;
+				while( i < max ) {
+					var c = StringTools.fastCodeAt(str,i++);
+					if( c == "}".code ) {
+						if( --count == 0 ) break;
+					} else if( c == "{".code )
+						count++;
+				}
+				if( count > 0 )
+					Context.error("Closing brace not found",make(1));
+				pos.min++;
+				start++;
+				var len = i - start - 1;
+				var expr = str.substr(start, len);
+				add(Context.parse(expr, make(len)));
+				pos.min++;
+				start++;
+			} else if( (c >= 'a'.code && c <= 'z'.code) || (c >= 'A'.code && c <= 'Z'.code) || c == '_'.code ) {
+				i++;
+				while( true ) {
+					var c = StringTools.fastCodeAt(str, i);
+					if( (c >= 'a'.code && c <= 'z'.code) || (c >= 'A'.code && c <= 'Z'.code) || (c >= '0'.code && c <= '9'.code) || c == '_'.code )
+						i++;
+					else
+						break;
+				}
+				var len = i - start;
+				var ident = str.substr(start, len);
+				add( { expr : EConst(CIdent(ident)), pos : make(len) } );
+			}
+			start = i;
+		}
+		var len = i - start;
+		if( len > 0 )
+			add({ expr : EConst(CString(str.substr(start,len))), pos : make(len) });
+		if( expr == null )
+			expr = { expr : EConst(CString("")), pos : make(0) };
+		return expr;
+	}
+	#end
+
+}

+ 4 - 0
std/js/_std/Std.hx

@@ -56,6 +56,10 @@
 		return untyped Math.floor(Math.random()*x);
 	}
 
+	@:macro public static function format( fmt : haxe.macro.Expr.ExprRequire<String> ) : haxe.macro.Expr.ExprRequire<String> {
+		return haxe.macro.Context.format(fmt);
+	}
+
 	static function __init__() : Void untyped {
 		String.prototype.__class__ = String;
 		String.__name__ = ["String"];

+ 4 - 0
std/neko/_std/Std.hx

@@ -60,6 +60,10 @@
 		return untyped Math._rand_int(Math.__rnd,x);
 	}
 
+	@:macro public static function format( fmt : haxe.macro.Expr.ExprRequire<String> ) : haxe.macro.Expr.ExprRequire<String> {
+		return haxe.macro.Format.format(fmt);
+	}
+
 	static function __init__() : Void untyped {
 		Int = { __name__ : ["Int"] };
 		Float = { __name__ : ["Float"] };

+ 4 - 0
std/php/_std/Std.hx

@@ -53,4 +53,8 @@
 	public static function random( x : Int ) : Int {
 		return untyped __call__("mt_rand", 0, x-1);
 	}
+
+	@:macro public static function format( fmt : haxe.macro.Expr.ExprRequire<String> ) : haxe.macro.Expr.ExprRequire<String> {
+		return haxe.macro.Context.format(fmt);
+	}
 }

+ 9 - 0
tests/unit/TestMisc.hx

@@ -312,4 +312,13 @@ class TestMisc extends Test {
 		eq(b.toString(), "-451.456nulltruefalseHello!laR");
 	}
 	
+	#if !macro
+	function testFormat()
+	{
+		var x = 5;
+		var y = 6;
+		eq(Std.format("$x${x+y}"), "511");
+	}
+	#end
+	
 }

+ 1 - 0
tests/unit/unit.hxml

@@ -1,6 +1,7 @@
 -cp ..
 -swf unit8.swf
 -swf-header 300:300:30:FFFFFF
+-swf-version 8
 -main unit.Test
 -swf-version 8
 params.hxml

+ 6 - 2
tests/unit/unit.hxproj

@@ -1,14 +1,16 @@
 <?xml version="1.0" encoding="utf-8"?>
-<project>
+<project version="2">
   <!-- Output SWF options -->
   <output>
-    <movie disabled="False" />
+    <movie outputType="Application" />
     <movie input="" />
     <movie path="unit8.swf" />
     <movie fps="30" />
     <movie width="300" />
     <movie height="300" />
     <movie version="8" />
+    <movie minorVersion="0" />
+    <movie platform="Flash Player" />
     <movie background="#FFFFFF" />
   </output>
   <!-- Other classes to be compiled into your SWF -->
@@ -62,4 +64,6 @@
     <option testMovie="OpenDocument" />
     <option testMovieCommand="http://dev.unit-tests/unit.html" />
   </options>
+  <!-- Plugin storage -->
+  <storage />
 </project>