PageRenderTime 28ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/src/haxe/structs/Structs.hx

http://structs.googlecode.com/
Haxe | 769 lines | 620 code | 94 blank | 55 comment | 85 complexity | 4e6ba60c1142996c15337d8e21341c4d MD5 | raw file
  1. package haxe.structs;
  2. #if macro
  3. import haxe.macro.PrettyPrint;
  4. import haxe.macro.Context;
  5. import haxe.macro.Expr;
  6. import haxe.macro.Type;
  7. import haxe.structs.internal.StructExtensions;
  8. import macrotools.MacroTools;
  9. import macrotools.TypeTools;
  10. using Lambda;
  11. #end
  12. /**
  13. * ...
  14. * @author waneck
  15. */
  16. typedef Structs<T> = //where T is AbstractStruct
  17. #if flash9 Int
  18. #elseif js js.webgl.TypedArray.DataView
  19. #elseif (neko || cpp) haxe.io.BytesData
  20. //#elseif php php.SplFixedArray
  21. //java http://www.javamex.com/tutorials/io/nio_buffers.shtml
  22. //c# Array of structs really
  23. //#else Array<Dynamic>
  24. #else
  25. #error "Platform not supported yet"
  26. #end;
  27. //typedef FixedStructs<T, Const> = Structs<T>;
  28. class StructsExtensions
  29. {
  30. @:macro public static function get(me:ExprRequire<Structs<Dynamic>>, index:Expr, ?fieldExpr:Expr):Expr
  31. {
  32. switch(fieldExpr.expr)
  33. {
  34. case EConst(c):
  35. switch(c)
  36. {
  37. case CIdent(n): if (n == "null") fieldExpr = null;
  38. default:
  39. }
  40. default:
  41. }
  42. #if display
  43. if (MacroTools.isDisplay(me))
  44. return me;
  45. else if (MacroTools.isDisplay(index))
  46. return index;
  47. else
  48. return getFieldCompletion(me, fieldExpr);
  49. #end
  50. return _get(me, index, fieldExpr);
  51. }
  52. #if (display && macro)
  53. private static function getFieldCompletion(me:Expr, fieldExpr:Expr):Expr
  54. {
  55. var isDisplay = false;
  56. if (fieldExpr != null)
  57. {
  58. switch(fieldExpr.expr)
  59. {
  60. case EDisplay(e, isCall):
  61. if (isCall) Context.error("Structs.get() cannot contain method calls", fieldExpr.pos);
  62. isDisplay = true;
  63. fieldExpr = e;
  64. default:
  65. }
  66. }
  67. var path = [];
  68. if (fieldExpr != null)
  69. path = MacroTools.getPath(fieldExpr);
  70. if (path[0] == "this")
  71. path.shift();
  72. var type = Context.typeof(me);
  73. var pos = Context.currentPos();
  74. //get the underlying struct type (Structs<MyType>, get MyType)
  75. var structType = switch(type)
  76. {
  77. case TType(tref, params):
  78. params[0];
  79. default: return {expr:EConst(CIdent("null")), pos:pos};
  80. };
  81. var structType = switch(structType)
  82. {
  83. case TType(tref, _): tref.toString();
  84. case TEnum(tref, _): tref.toString();
  85. case TInst(tref, _): tref.toString();
  86. default: return {expr:EConst(CIdent("null")), pos:pos};
  87. };
  88. var pack:Array<String> = structType.split(".");
  89. var name = pack.pop();
  90. var block = [];
  91. block.push({
  92. expr: EVars([{
  93. name:"_",
  94. type:TPath({
  95. pack:pack,
  96. name:name,
  97. params:[],
  98. sub:null
  99. }),
  100. expr:{expr:EConst(CIdent("null")), pos:pos}
  101. }]),
  102. pos:pos
  103. });
  104. block.push({expr:EConst(CIdent("_")), pos:pos});
  105. var curExpr = {expr:EBlock(block), pos:pos};
  106. for (p in path)
  107. {
  108. if (MacroTools.isUpperFirst(p))
  109. curExpr = {expr:EType(curExpr, p), pos:pos};
  110. else
  111. curExpr = {expr:EField(curExpr, p), pos:pos};
  112. }
  113. return if (isDisplay)
  114. {expr:EDisplay(curExpr, false), pos:pos};
  115. else
  116. curExpr;
  117. }
  118. #end
  119. @:macro public static function foreach(me:ExprRequire<Structs<Dynamic>>, createdVar:Expr, block:Expr):Expr
  120. {
  121. var type = Context.typeof(me);
  122. var pos = Context.currentPos();
  123. #if display
  124. var stype = getStructType(type, me.pos);
  125. var path = TypeTools.path(Context.follow(stype));
  126. var struct = {totalBytes:0, isNativeType:(path == "Int" || path == "Float"), path:path, iterator:function() return [].iterator() };
  127. #else
  128. var struct = StructInfo.get(getStructType(type, me.pos));
  129. #end
  130. var createdVar = switch(createdVar.expr)
  131. {
  132. case EConst(c):
  133. switch(c)
  134. {
  135. case CIdent(s), CType(s): s;
  136. default: null;
  137. }
  138. default:null;
  139. }
  140. var blockArray = switch(block.expr)
  141. {
  142. case EBlock(bl): bl;
  143. default:
  144. var ret = [block];
  145. block = {expr:EBlock(ret), pos:block.pos};
  146. ret;
  147. };
  148. var newBlock = [];
  149. if (createdVar == null) Context.error("Foreach expression must be 'structs.foreach(myVar, {...})'", pos);
  150. var it = createdVar + "__i__";
  151. var len = createdVar + "__len__";
  152. newBlock.push({
  153. expr:EVars([
  154. {
  155. name:it,
  156. type:null,
  157. expr:{expr:EConst(CInt((-struct.totalBytes) + "")), pos:pos}
  158. },
  159. {
  160. name:len,
  161. type:null,
  162. expr:MacroTools.mkCall(["haxe", "structs", "internal", "StructsInternal", "internalSize"], [me], pos)
  163. }]),
  164. pos:pos
  165. });
  166. newBlock.push({
  167. expr:EWhile({ //while
  168. expr:EBinop(OpLt, { //<
  169. expr:EBinop(OpAssignOp(OpAdd), {expr:EConst(CIdent(it)), pos:pos}, {expr:EConst(CInt(struct.totalBytes + "")), pos:pos}),
  170. pos:pos
  171. }, {expr:EConst(CIdent(len)), pos:pos} ),
  172. pos:pos
  173. }, block, true),
  174. pos:pos
  175. });
  176. var newArgs = [];
  177. var offset = {expr:EConst(CIdent(it)), pos:pos};
  178. for (field in struct)
  179. {
  180. newArgs.push(getFieldExpr(me, offset, field, pos));
  181. }
  182. var pack = struct.path.split(".");
  183. var name = pack.pop();
  184. var enew = if (!struct.isNativeType)
  185. {
  186. expr:ENew({ pack:pack, name:name, params:[], sub:null }, newArgs),
  187. pos:pos
  188. };
  189. else
  190. newArgs[0];
  191. blockArray.unshift({
  192. expr:EVars([{
  193. name:createdVar,
  194. type:null,
  195. expr:enew
  196. }]),
  197. pos:pos
  198. });
  199. return {expr:EBlock(newBlock), pos:pos};
  200. }
  201. @:macro public static function set(fieldsOrNewStruct:Array<Expr>):Expr
  202. {
  203. #if display
  204. //first check to see if there is EDisplay here
  205. //if not, ignore
  206. var i = 0;
  207. for (e in fieldsOrNewStruct)
  208. {
  209. if (MacroTools.isDisplay(e))
  210. {
  211. if (i < 2)
  212. return e;
  213. else
  214. return getFieldCompletion(fieldsOrNewStruct[0], e);
  215. }
  216. switch(e.expr)
  217. {
  218. case EBinop(op, e1, e2):
  219. if (MacroTools.isDisplay(e1))
  220. return getFieldCompletion(fieldsOrNewStruct[0], e1);
  221. else if (MacroTools.isDisplay(e2))
  222. return e2;
  223. default:
  224. }
  225. i++;
  226. }
  227. return {expr:EConst(CIdent("null")), pos:Context.currentPos()};
  228. #else
  229. if (fieldsOrNewStruct.length < 3)
  230. Context.error("Incorrect number of call arguments", Context.currentPos());
  231. var me = fieldsOrNewStruct.shift();
  232. var index = fieldsOrNewStruct.shift();
  233. return _set(me, index, fieldsOrNewStruct);
  234. #end
  235. }
  236. @:macro public static function structsLength(me:ExprRequire<Structs<Dynamic>>):Expr
  237. {
  238. var pos = Context.currentPos();
  239. #if display
  240. return {expr:ECons(CInt("0")), pos:pos};
  241. #else
  242. var type = Context.typeof(me);
  243. var struct = StructInfo.get(getStructType(type, me.pos));
  244. var sizeCall = MacroTools.mkCall(["haxe", "structs", "internal", "StructsInternal", "internalSize"], [me], pos);
  245. var div = {expr:EBinop(OpDiv, sizeCall, {expr:EConst(CInt(struct.totalBytes + "")), pos:pos}), pos:pos};
  246. return MacroTools.mkCall(["Std", "int"], [div], pos);
  247. #end
  248. }
  249. @:macro public static function structs(cl:ExprRequire<Class<Dynamic>>, size:Int):Expr
  250. {
  251. var clpath = MacroTools.getPath(cl);
  252. var type = Context.typeof( Context.parse("{ var _:" + clpath.join(".") + "; _;}", cl.pos) );
  253. var pos = Context.currentPos();
  254. //get the underlying struct type (Structs<MyType>, get MyType)
  255. #if display
  256. var struct = {totalBytes:0};
  257. #else
  258. var struct = StructInfo.get(type);
  259. #end
  260. var call = MacroTools.mkCall(["haxe", "structs", "internal", "StructsInternal", "internalMake"], [{expr:EConst(CInt((size * struct.totalBytes) + "")), pos:pos}], pos);
  261. var block = [];
  262. var clname = clpath.pop();
  263. var structType = TPType(TPath({
  264. pack:clpath,
  265. name:clname,
  266. params:[],
  267. sub:null
  268. }));
  269. block.push({
  270. expr: EVars([{
  271. name:"_",
  272. type:TPath({
  273. pack:["haxe", "structs"],
  274. name:"Structs",
  275. params:[structType],
  276. sub:null
  277. }),
  278. expr:call
  279. }]),
  280. pos:pos
  281. });
  282. block.push({expr:EConst(CIdent("_")), pos:pos});
  283. return {expr:EBlock(block), pos:pos};
  284. }
  285. public static function dispose(s:Structs<Dynamic>):Void
  286. {
  287. #if flash9
  288. //haxe.management.Manager.free(s);
  289. #else
  290. #end
  291. }
  292. #if macro
  293. private static function _set(me:Expr, index:Expr, fieldsOrNewStruct:Array<Expr>):Expr
  294. {
  295. var type = Context.typeof(me);
  296. var pos = Context.currentPos();
  297. var block = [];
  298. //get the underlying struct type (Structs<MyType>, get MyType)
  299. var struct = StructInfo.get(getStructType(type, me.pos));
  300. var bytesOffset = {
  301. expr:EBinop(OpMult, index, {
  302. expr:EConst(CInt(struct.totalBytes + "")),
  303. pos:index.pos
  304. }),
  305. pos:index.pos
  306. };
  307. switch(index.expr)
  308. {
  309. case EConst(c):
  310. default:
  311. block.push({expr:EVars([{ name:"__offset__", type:null, expr:bytesOffset}]), pos:pos});
  312. bytesOffset = {expr:EConst(CIdent("__offset__")), pos:pos};
  313. }
  314. if (fieldsOrNewStruct.length < 1) Context.error("Too few arguments", pos);
  315. function separateOpAssign(expr:Expr, throwErrors:Bool):{leftSide:Array<String>, rightSide:Expr, assignOp:Null<Binop>}
  316. {
  317. return switch(expr.expr)
  318. {
  319. case EParenthesis(p): separateOpAssign(p, throwErrors);
  320. case EBinop(op, e1, e2):
  321. var assignOp = null;
  322. switch(op)
  323. {
  324. case OpAssignOp(op):
  325. assignOp = op;
  326. case OpAssign:
  327. default:
  328. if (throwErrors) Context.error("Invalid expression. An assign operation was expected", expr.pos);
  329. else return null;
  330. }
  331. var leftSide = MacroTools.getPath(e1);
  332. {leftSide:leftSide, rightSide:e2, assignOp:assignOp};
  333. default:
  334. if (throwErrors) Context.error("Invalid expression. An assign operation was expected", expr.pos);
  335. else null;
  336. }
  337. }
  338. var assign = separateOpAssign(fieldsOrNewStruct[0], false);
  339. if (assign == null)
  340. {
  341. if (fieldsOrNewStruct.length > 1)
  342. separateOpAssign(fieldsOrNewStruct[0], true); //throw error
  343. var e = setFieldExpr(me, bytesOffset, {type:SFStruct(struct), byteOffset:0}, fieldsOrNewStruct[0], null, pos);
  344. trace(PrettyPrint.make(e));
  345. return e;
  346. }
  347. for (assignField in fieldsOrNewStruct)
  348. {
  349. var struct = struct;
  350. var assign = separateOpAssign(assignField, true);
  351. var fieldOffset = 0;
  352. var lastF = null;
  353. if (assign.leftSide[0] == "this")
  354. {
  355. lastF = {name:"this", type:SFStruct(struct), byteOffset:0};
  356. assign.leftSide.shift();
  357. }
  358. for (field in assign.leftSide)
  359. {
  360. if (lastF != null)
  361. {
  362. switch(lastF.type)
  363. {
  364. case SFStruct(s):
  365. struct = s;
  366. default:
  367. Context.error("Field " + lastF.name + " does not contain fields", assign.rightSide.pos);
  368. }
  369. fieldOffset += lastF.byteOffset;
  370. }
  371. lastF = struct.getField(field);
  372. if (lastF == null)
  373. {
  374. Context.error("Type " + struct.path + " does not contain field " + field, assign.rightSide.pos);
  375. }
  376. }
  377. var bytesOffset = if (fieldOffset != 0)
  378. {
  379. expr:EBinop(OpAdd, bytesOffset, {
  380. expr: EConst(CInt(fieldOffset + "")),
  381. pos:pos
  382. }),
  383. pos:pos
  384. };
  385. else
  386. bytesOffset;
  387. var e = setFieldExpr(me, bytesOffset, cast lastF, assign.rightSide, assign.assignOp, pos);
  388. block.push(e);
  389. }
  390. var e = if (block.length > 1) {expr:EBlock(block), pos:pos}; else block[0];
  391. trace(PrettyPrint.make(e));
  392. return e;
  393. }
  394. /*TODO
  395. private static function binopToCall(op:Binop, e1:Expr, e2:Expr):String
  396. {
  397. var func = switch(op)
  398. {
  399. case OpAdd: "add";
  400. case OpSub: "sub";
  401. case OpMult: "mul";
  402. case OpDiv: "div";
  403. case OpMod: "mod";
  404. case OpShr: "shr";
  405. case OpShl: "shl";
  406. case OpUShr: "ushr";
  407. case OpAnd: "and";
  408. case OpOr: "or";
  409. case OpXor: "xor";
  410. //case OpNeg: "neg";
  411. //case OpNegBits: "complement";
  412. }
  413. }*/
  414. private static function platformSetExpr(me:Expr, bytesOffset:Expr, field:{type:StructFieldType, byteOffset:Int}, setExpr:Expr, pos:Position):Expr
  415. {
  416. var func = switch(field.type)
  417. {
  418. case SFInt: "setInt32";
  419. case SFShort: "setInt16";
  420. case SFByte: "setInt8";
  421. case SFDouble: "setDouble";
  422. case SFSingle: "setSingle";
  423. case SFInt32: "setInt32h";
  424. case SFInt64: "setInt64";
  425. default: throw "assert";
  426. };
  427. return MacroTools.mkCall(["haxe", "structs", "internal", "StructsInternal", func], [me, {expr:EBinop(OpAdd, bytesOffset, {expr:EConst(CInt(field.byteOffset + "")), pos:pos}), pos:pos}, setExpr], pos);
  428. }
  429. private static function setFieldExpr(me:Expr, bytesOffset:Expr, field:{type:StructFieldType, byteOffset:Int}, setExpr:Expr, assignOp:Null<Binop>, pos:Position):Expr
  430. {
  431. var field = switch(field.type)
  432. {
  433. case SFStruct(info):
  434. if (info.isNativeType)
  435. info.getField("this");
  436. else
  437. field;
  438. default:field;
  439. };
  440. return switch(field.type)
  441. {
  442. case SFInt, SFShort, SFByte, SFDouble, SFSingle, SFInt32, SFInt64:
  443. if (assignOp != null)
  444. {
  445. setExpr =
  446. {
  447. expr:EBinop(assignOp, getFieldExpr(me, bytesOffset, field, pos), setExpr),
  448. pos:pos
  449. };
  450. }
  451. platformSetExpr(me, bytesOffset, field, setExpr, pos);
  452. case SFStruct(info):
  453. var offset = bytesOffset;
  454. var exprs = [];
  455. if (field.byteOffset != 0)
  456. {
  457. exprs.push({
  458. expr:EVars([{ name:"__offset__", type:null, expr:{
  459. expr:EBinop(OpAdd, bytesOffset, {
  460. expr:EConst(CInt(field.byteOffset + "")),
  461. pos:pos
  462. }),
  463. pos: pos
  464. } }]),
  465. pos:pos
  466. });
  467. offset = {expr:EConst(CIdent("__offset__")), pos:pos};
  468. }
  469. switch(setExpr.expr)
  470. {
  471. case ENew(path, params):
  472. var n = info.path.lastIndexOf(".");
  473. var n = if (n == -1) info.path; else info.path.substr(n);
  474. if (path.name != n)
  475. {
  476. Context.error("Expecting type " + info.path + " but got " + path.name, setExpr.pos);
  477. }
  478. var fields = Lambda.array(info);
  479. for (i in 0...params.length)
  480. {
  481. var param = params[i];
  482. var field = fields[i];
  483. exprs.push(setFieldExpr(me, offset, field, param, null, param.pos));
  484. }
  485. default:
  486. exprs.push({
  487. expr:EVars([{ name:"__setval__", type:null, expr:setExpr }]),
  488. pos:pos
  489. });
  490. setExpr = {expr:EConst(CIdent("__setval__")), pos:pos};
  491. for (field in info)
  492. {
  493. var setExpr = {expr:EField(setExpr, field.name), pos:setExpr.pos};
  494. exprs.push(setFieldExpr(me, offset, field, setExpr, null, setExpr.pos));
  495. }
  496. }
  497. if (exprs.length == 1)
  498. exprs[0];
  499. else
  500. {
  501. expr:EBlock(exprs),
  502. pos:pos
  503. };
  504. }
  505. }
  506. static function getStructType(type:Type, pos:Position):Type
  507. {
  508. return switch(type)
  509. {
  510. case TType(tref, params):
  511. switch(tref.toString())
  512. {
  513. case "haxe.structs.Structs":
  514. if (params.length != 1)
  515. Context.error("Incorrect number of arguments for Structs<Structs.T>", pos);
  516. params[0];
  517. default:
  518. getStructType(Context.follow(type, true), pos);
  519. }
  520. default: Context.error("Incorrect argument type. Expected haxe.structs.Structs<Structs.T>, but got " + Std.string(type), pos);
  521. }
  522. }
  523. static function _get(me:Expr, index:Expr, fieldExpr:Null<Expr>):Expr
  524. {
  525. var type = Context.typeof(me);
  526. var pos = Context.currentPos();
  527. //get the underlying struct type (Structs<MyType>, get MyType)
  528. var struct = StructInfo.get(getStructType(type, me.pos));
  529. var bytesOffset = {
  530. expr:EBinop(OpMult, index, {
  531. expr:EConst(CInt(struct.totalBytes + "")),
  532. pos:index.pos
  533. }),
  534. pos:index.pos
  535. };
  536. var realField = null;
  537. if (fieldExpr != null)
  538. {
  539. realField = haxe.macro.MacroTools.getPath(fieldExpr);
  540. } else {
  541. var e = getFieldExpr(me, bytesOffset, {type:SFStruct(struct), byteOffset:0}, pos);
  542. trace(PrettyPrint.make(e));
  543. return e;
  544. }
  545. if (realField[0] == "this") realField.splice(0, 1);
  546. var fieldOffset = 0;
  547. var lastF = null;
  548. for (field in realField)
  549. {
  550. if (lastF != null)
  551. {
  552. switch(lastF.type)
  553. {
  554. case SFStruct(s):
  555. struct = s;
  556. default:
  557. Context.error("Field " + lastF.name + " does not contain fields", fieldExpr.pos);
  558. }
  559. fieldOffset += lastF.byteOffset;
  560. }
  561. lastF = struct.getField(field);
  562. if (lastF == null)
  563. {
  564. Context.error("Type " + struct.path + " does not contain field " + field, fieldExpr.pos);
  565. }
  566. }
  567. if (fieldOffset != 0)
  568. bytesOffset = {
  569. expr:EBinop(OpAdd, bytesOffset, {
  570. expr: EConst(CInt(fieldOffset + "")),
  571. pos:pos
  572. }),
  573. pos:pos
  574. };
  575. var e = getFieldExpr(me, bytesOffset, cast lastF, pos);
  576. trace(PrettyPrint.make(e));
  577. return e;
  578. }
  579. private static function platformGetExpr(me:Expr, bytesOffset:Expr, field:{type:StructFieldType, byteOffset:Int}, pos:Position):Expr
  580. {
  581. return switch(field.type)
  582. {
  583. /*case SFInt32:
  584. if (Context.defined("neko")) //special case for 31 bits ints
  585. {
  586. var getI16_1 = platformGetExpr(me, bytesOffset, {type:SFShort, byteOffset:field.byteOffset}, pos);
  587. var getI16_2 = platformGetExpr(me, bytesOffset, {type:SFShort, byteOffset:field.byteOffset + 2}, pos);
  588. MacroTools.mkCall(["haxe", "Int32", "make"], [getI16_1, getI16_2], pos);
  589. } else {
  590. var getI32 = platformGetExpr(me, bytesOffset, {type:SFInt, byteOffset:field.byteOffset}, pos);
  591. MacroTools.mkCall(["haxe", "Int32", "ofInt"], [getI32], pos);
  592. }*/
  593. case SFInt, SFShort, SFByte, SFDouble, SFSingle, SFInt32, SFInt64:
  594. var func = switch(field.type)
  595. {
  596. case SFInt: "getInt32";
  597. case SFShort: "getInt16";
  598. case SFByte: "getInt8";
  599. case SFDouble: "getDouble";
  600. case SFSingle: "getSingle";
  601. case SFInt64: "getInt64";
  602. case SFInt32: "getInt32h";
  603. default: null;
  604. };
  605. MacroTools.mkCall(["haxe", "structs", "internal", "StructsInternal", func], [me, {expr:EBinop(OpAdd, bytesOffset, {expr:EConst(CInt(field.byteOffset + "")), pos:pos}), pos:pos}], pos);
  606. case SFStruct(_): throw "assert"; //this case is already ruled out by getFieldExpr
  607. }
  608. }
  609. private static function getFieldExpr(me:Expr, bytesOffset:Expr, field:{type:StructFieldType, byteOffset:Int}, pos:Position):Expr
  610. {
  611. var field = switch(field.type)
  612. {
  613. case SFStruct(info):
  614. if (info.isNativeType)
  615. info.getField("this");
  616. else
  617. field;
  618. default: field;
  619. };
  620. return switch(field.type)
  621. {
  622. case SFInt, SFShort, SFByte, SFDouble, SFSingle, SFInt32, SFInt64:
  623. platformGetExpr(me, bytesOffset, field, pos);
  624. case SFStruct(info):
  625. //var __offset__ = me + bytesOffset;
  626. var offset = bytesOffset;
  627. var exprs = [];
  628. if (field.byteOffset != 0)
  629. {
  630. exprs.push({
  631. expr:EVars([{ name:"__offset__", type:null, expr:{
  632. expr:EBinop(OpAdd, bytesOffset, {
  633. expr:EConst(CInt(field.byteOffset + "")),
  634. pos:pos
  635. }),
  636. pos: pos
  637. } }]),
  638. pos:pos
  639. });
  640. offset = {expr:EConst(CIdent("__offset__")), pos:pos};
  641. }
  642. var newArgs = [];
  643. for (field in info)
  644. {
  645. newArgs.push(getFieldExpr(me, offset, field, pos));
  646. }
  647. var pack = info.path.split(".");
  648. var name = pack.pop();
  649. exprs.push({
  650. expr:ENew({ pack:pack, name:name, params:[], sub:null }, newArgs),
  651. pos:pos
  652. });
  653. if (exprs.length == 1)
  654. exprs[0];
  655. else
  656. {
  657. expr:EBlock(exprs),
  658. pos:pos
  659. };
  660. }
  661. }
  662. #end
  663. @:macro public static function optimize(me:Expr):Expr
  664. {
  665. //here we will run a deep analysis on the block 'me';
  666. //as a first need, all unresolved CIdent will be considered as this.
  667. //we will then inline all methods that are from structs
  668. //then, we will detect the make() and makeFrom() patterns, and all structs will be unrolled to temp variables
  669. //we will then treat field access as var access, and also perform one pass of escape analysis
  670. //this will deterine all structs that need to be remade, and also will determine the vars that can be reused.
  671. //This will prevent the creation of lots of temp struct variables, and also will allow for any haxe target to benefit
  672. //from having stack allocated instances
  673. return null;
  674. }
  675. }