diff --git a/.nb-gradle-properties b/.nb-gradle-properties index b18f6c4..eecdb26 100644 --- a/.nb-gradle-properties +++ b/.nb-gradle-properties @@ -9,7 +9,9 @@ runClient - + + -Xdebug + run @@ -22,5 +24,14 @@ -Dfml.coreMods.load=minetweaker.mc172.transformer.MineTweakerTransformer + + run.single + no + + ${project}:runClient + + + + diff --git a/MineTweaker3-API/src/main/java/minetweaker/IBracketHandler.java b/MineTweaker3-API/src/main/java/minetweaker/IBracketHandler.java index 36ca12e..616449e 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/IBracketHandler.java +++ b/MineTweaker3-API/src/main/java/minetweaker/IBracketHandler.java @@ -1,6 +1,7 @@ package minetweaker; import java.util.List; +import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.parser.Token; import stanhebben.zenscript.symbols.IZenSymbol; @@ -23,8 +24,9 @@ public interface IBracketHandler { * * If the series of tokens is unrecognized, this method should return null. * + * @param environment global compilation environment * @param tokens token stream to be detected * @return the resolved symbol, or null */ - public IZenSymbol resolve(List tokens); + public IZenSymbol resolve(IEnvironmentGlobal environment, List tokens); } diff --git a/MineTweaker3-API/src/main/java/minetweaker/MineTweakerAPI.java b/MineTweaker3-API/src/main/java/minetweaker/MineTweakerAPI.java index 08d3f42..30bd0bf 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/MineTweakerAPI.java +++ b/MineTweaker3-API/src/main/java/minetweaker/MineTweakerAPI.java @@ -29,6 +29,7 @@ import stanhebben.zenscript.symbols.IZenSymbol; import stanhebben.zenscript.symbols.SymbolJavaStaticField; import stanhebben.zenscript.symbols.SymbolJavaStaticGetter; import stanhebben.zenscript.symbols.SymbolJavaStaticMethod; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.type.natives.JavaMethod; /** @@ -333,7 +334,7 @@ public class MineTweakerAPI { * @return corresponding symbol */ public static IZenSymbol getJavaStaticMethodSymbol(Class cls, String name, Class... arguments) { - JavaMethod method = JavaMethod.get(GlobalRegistry.getTypeRegistry(), cls, name, arguments); + IJavaMethod method = JavaMethod.get(GlobalRegistry.getTypeRegistry(), cls, name, arguments); return new SymbolJavaStaticMethod(method); } @@ -347,7 +348,7 @@ public class MineTweakerAPI { * @return corresponding symbol */ public static IZenSymbol getJavaStaticGetterSymbol(Class cls, String name) { - JavaMethod method = JavaMethod.get(GlobalRegistry.getTypeRegistry(), cls, name); + IJavaMethod method = JavaMethod.get(GlobalRegistry.getTypeRegistry(), cls, name); return new SymbolJavaStaticGetter(method); } @@ -379,7 +380,7 @@ public class MineTweakerAPI { * @param arguments argument types * @return java method */ - public static JavaMethod getJavaMethod(Class cls, String name, Class... arguments) { + public static IJavaMethod getJavaMethod(Class cls, String name, Class... arguments) { return JavaMethod.get(GlobalRegistry.getTypeRegistry(), cls, name, arguments); } } diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/player/IPlayer.java b/MineTweaker3-API/src/main/java/minetweaker/api/player/IPlayer.java index ffa9c8a..ce7436e 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/player/IPlayer.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/player/IPlayer.java @@ -6,7 +6,6 @@ package minetweaker.api.player; -import java.util.List; import minetweaker.api.chat.IChatMessage; import minetweaker.api.data.IData; import minetweaker.api.item.IItemStack; @@ -53,5 +52,12 @@ public interface IPlayer { @ZenGetter("currentItem") public IItemStack getCurrentItem(); + @ZenGetter("creative") + public boolean isCreative(); + + @ZenGetter("adventure") + public boolean isAdventure(); + + // not an exposed method. risks abuse public void openBrowser(String url); } diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/recipes/IRecipeManager.java b/MineTweaker3-API/src/main/java/minetweaker/api/recipes/IRecipeManager.java index c111cb8..4172701 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/recipes/IRecipeManager.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/recipes/IRecipeManager.java @@ -28,28 +28,26 @@ public interface IRecipeManager { * * @param output recipe output * @param ingredients recipe ingredients - * @param mirrored indicates if the mirrored recipe should be valid too (optional) + * @param function recipe function (optional) */ @ZenMethod public void addShaped( IItemStack output, IIngredient[][] ingredients, - @Optional boolean mirrored); + @Optional IRecipeFunction function); /** - * Adds a shaped recipe. + * Adds a mirrored shaped recipe. * * @param output recipe output * @param ingredients recipe ingredients * @param function recipe function (optional) - * @param mirrored indicates if the mirrored recipe should be valid too (optional) */ @ZenMethod - public void addShaped( + public void addShapedMirrored( IItemStack output, IIngredient[][] ingredients, - IRecipeFunction function, - @Optional boolean mirrored); + @Optional IRecipeFunction function); /** * Adds a shapeless recipe. diff --git a/MineTweaker3-API/src/main/java/minetweaker/runtime/GlobalRegistry.java b/MineTweaker3-API/src/main/java/minetweaker/runtime/GlobalRegistry.java index a115465..6774485 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/runtime/GlobalRegistry.java +++ b/MineTweaker3-API/src/main/java/minetweaker/runtime/GlobalRegistry.java @@ -13,6 +13,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import minetweaker.IBracketHandler; @@ -35,6 +36,7 @@ import stanhebben.zenscript.symbols.SymbolPackage; import stanhebben.zenscript.symbols.SymbolType; import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.type.ZenTypeNative; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.ZenPosition; @@ -105,9 +107,9 @@ public class GlobalRegistry { } } - public static IZenSymbol resolveBracket(List tokens) { + public static IZenSymbol resolveBracket(IEnvironmentGlobal environment, List tokens) { for (IBracketHandler handler : bracketHandlers) { - IZenSymbol symbol = handler.resolve(tokens); + IZenSymbol symbol = handler.resolve(environment, tokens); if (symbol != null) { return symbol; } @@ -117,7 +119,7 @@ public class GlobalRegistry { } public static IZenSymbol getStaticFunction(Class cls, String name, Class... arguments) { - JavaMethod method = JavaMethod.get(types, cls, name, arguments); + IJavaMethod method = JavaMethod.get(types, cls, name, arguments); if (method == null) return null; return new SymbolJavaStaticMethod(method); } @@ -180,8 +182,8 @@ public class GlobalRegistry { } @Override - public IZenSymbol getBracketed(List tokens) { - return resolveBracket(tokens); + public IZenSymbol getBracketed(IEnvironmentGlobal environment, List tokens) { + return resolveBracket(environment, tokens); } @Override @@ -266,5 +268,15 @@ public class GlobalRegistry { public void warning(ZenPosition position, String message) { MineTweakerAPI.logWarning(position.toString() + " > " + message); } + + @Override + public Set getClassNames() { + return classes.keySet(); + } + + @Override + public byte[] getClass(String name) { + return classes.get(name); + } } } diff --git a/MineTweaker3-API/src/main/java/minetweaker/runtime/MTTweaker.java b/MineTweaker3-API/src/main/java/minetweaker/runtime/MTTweaker.java index 965b5b0..7dd2c61 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/runtime/MTTweaker.java +++ b/MineTweaker3-API/src/main/java/minetweaker/runtime/MTTweaker.java @@ -36,6 +36,8 @@ import stanhebben.zenscript.parser.ParseException; * @author Stan Hebben */ public class MTTweaker implements ITweaker { + private static final boolean DEBUG = true; + private final List actions = new ArrayList(); private final Set wereStuck = new LinkedHashSet(); private final Map stuckOverridable = new HashMap(); @@ -61,8 +63,9 @@ public class MTTweaker implements ITweaker { } action.apply(); - actions.add(action); } + + actions.add(action); } @Override @@ -148,7 +151,7 @@ public class MTTweaker implements ITweaker { try { String filename = script.getGroupName(); System.out.println("MineTweaker: Loading " + filename); - compileScripts(filename, files, environmentGlobal); + compileScripts(filename, files, environmentGlobal, DEBUG); // execute scripts ZenModule module = new ZenModule(classes, MineTweakerAPI.class.getClassLoader()); diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/block/MCItemBlock.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/block/MCItemBlock.java index 3ae2e5b..89eee2b 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/block/MCItemBlock.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/block/MCItemBlock.java @@ -59,7 +59,7 @@ public class MCItemBlock implements IBlock { @Override public boolean matches(IBlock block) { - if (getDefinition() != block.getDefinition()) { + /*if (getDefinition() != block.getDefinition()) { System.out.println("Different block"); return false; } @@ -74,11 +74,11 @@ public class MCItemBlock implements IBlock { return false; } - return true; + return true;*/ -/* return getDefinition() == block.getDefinition() + return getDefinition() == block.getDefinition() && (getMeta() == OreDictionary.WILDCARD_VALUE || getMeta() == block.getMeta()) - && (getTileData() == null || (block.getTileData() != null && block.getTileData().contains(getTileData())));*/ + && (getTileData() == null || (block.getTileData() != null && block.getTileData().contains(getTileData()))); } @Override diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/brackets/ItemBracketHandler.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/brackets/ItemBracketHandler.java index 114d58c..5bed0c4 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/brackets/ItemBracketHandler.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/brackets/ItemBracketHandler.java @@ -18,14 +18,15 @@ import static minetweaker.api.minecraft.MineTweakerMC.getIItemStackWildcardSize; import net.minecraft.item.Item; import net.minecraftforge.oredict.OreDictionary; import stanhebben.zenscript.ZenTokener; +import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.expression.ExpressionInt; -import stanhebben.zenscript.expression.ExpressionJavaCallStatic; +import stanhebben.zenscript.expression.ExpressionCallStatic; import stanhebben.zenscript.expression.ExpressionString; import stanhebben.zenscript.expression.partial.IPartialExpression; import stanhebben.zenscript.parser.Token; import stanhebben.zenscript.symbols.IZenSymbol; import stanhebben.zenscript.type.ZenType; -import stanhebben.zenscript.type.natives.JavaMethod; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.util.ZenPosition; /** @@ -64,8 +65,8 @@ public class ItemBracketHandler implements IBracketHandler { } private final IZenSymbol symbolAny; - private final JavaMethod method; - private final JavaMethod method2; + private final IJavaMethod method; + private final IJavaMethod method2; public ItemBracketHandler() { symbolAny = MineTweakerAPI.getJavaStaticFieldSymbol( @@ -82,7 +83,7 @@ public class ItemBracketHandler implements IBracketHandler { } @Override - public IZenSymbol resolve(List tokens) { + public IZenSymbol resolve(IEnvironmentGlobal environment, List tokens) { // any symbol if (tokens.size() == 1 && tokens.get(0).getValue().equals("*")) { return symbolAny; @@ -111,30 +112,17 @@ public class ItemBracketHandler implements IBracketHandler { } } - return find(tokens, fromIndex, toIndex, meta); + return find(environment, tokens, fromIndex, toIndex, meta); } - private IZenSymbol find(List tokens, int startIndex, int endIndex, int meta) { - /*StringBuilder test = new StringBuilder(); - for (int i = startIndex; i < endIndex; i++) { - Token token = tokens.get(i); - if (i > startIndex) { - test.append(' '); - } - test.append(token.getValue()); - test.append(" ("); - test.append(token.getType()); - test.append(")"); - } - System.out.println("Find " + test);*/ - + private IZenSymbol find(IEnvironmentGlobal environment, List tokens, int startIndex, int endIndex, int meta) { if (endIndex == startIndex + 1 && tokens.get(startIndex).getType() == ZenTokener.T_INTVALUE) { int id = Integer.parseInt(tokens.get(startIndex).getValue()); if (id < 0 || id > Item.itemsList.length || Item.itemsList[id] == null) { return null; } - return new ItemReferenceSymbolId(id, meta); + return new ItemReferenceSymbolId(environment, id, meta); } StringBuilder valueBuilder = new StringBuilder(); @@ -144,25 +132,28 @@ public class ItemBracketHandler implements IBracketHandler { } if (itemNames.containsKey(valueBuilder.toString())) { - return new ItemReferenceSymbol(valueBuilder.toString(), meta); + return new ItemReferenceSymbol(environment, valueBuilder.toString(), meta); } return null; } private class ItemReferenceSymbol implements IZenSymbol { + private final IEnvironmentGlobal environment; private final String name; private final int meta; - public ItemReferenceSymbol(String name, int meta) { + public ItemReferenceSymbol(IEnvironmentGlobal environment, String name, int meta) { + this.environment = environment; this.name = name; this.meta = meta; } @Override public IPartialExpression instance(ZenPosition position) { - return new ExpressionJavaCallStatic( + return new ExpressionCallStatic( position, + environment, method, new ExpressionString(position, name), new ExpressionInt(position, meta, ZenType.INT)); @@ -170,18 +161,21 @@ public class ItemBracketHandler implements IBracketHandler { } private class ItemReferenceSymbolId implements IZenSymbol { + private final IEnvironmentGlobal environment; private final int id; private final int meta; - public ItemReferenceSymbolId(int id, int meta) { + public ItemReferenceSymbolId(IEnvironmentGlobal environment, int id, int meta) { + this.environment = environment; this.id = id; this.meta = meta; } @Override public IPartialExpression instance(ZenPosition position) { - return new ExpressionJavaCallStatic( + return new ExpressionCallStatic( position, + environment, method2, new ExpressionInt(position, id, ZenType.INT), new ExpressionInt(position, meta, ZenType.INT)); diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/brackets/LiquidBracketHandler.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/brackets/LiquidBracketHandler.java index b1eca98..bee40e9 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/brackets/LiquidBracketHandler.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/brackets/LiquidBracketHandler.java @@ -9,11 +9,13 @@ import minetweaker.runtime.GlobalRegistry; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; -import stanhebben.zenscript.expression.ExpressionJavaCallStatic; +import stanhebben.zenscript.compiler.IEnvironmentGlobal; +import stanhebben.zenscript.expression.ExpressionCallStatic; import stanhebben.zenscript.expression.ExpressionString; import stanhebben.zenscript.expression.partial.IPartialExpression; import stanhebben.zenscript.parser.Token; import stanhebben.zenscript.symbols.IZenSymbol; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.ZenPosition; @@ -33,17 +35,17 @@ public class LiquidBracketHandler implements IBracketHandler { } @Override - public IZenSymbol resolve(List tokens) { + public IZenSymbol resolve(IEnvironmentGlobal environment, List tokens) { if (tokens.size() > 2) { if (tokens.get(0).getValue().equals("liquid") && tokens.get(1).getValue().equals(":")) { - return find(tokens, 2, tokens.size()); + return find(environment, tokens, 2, tokens.size()); } } return null; } - private IZenSymbol find(List tokens, int startIndex, int endIndex) { + private IZenSymbol find(IEnvironmentGlobal environment, List tokens, int startIndex, int endIndex) { StringBuilder valueBuilder = new StringBuilder(); for (int i = startIndex; i < endIndex; i++) { Token token = tokens.get(i); @@ -52,29 +54,32 @@ public class LiquidBracketHandler implements IBracketHandler { Fluid fluid = FluidRegistry.getFluid(valueBuilder.toString()); if (fluid != null) { - return new LiquidReferenceSymbol(valueBuilder.toString()); + return new LiquidReferenceSymbol(environment, valueBuilder.toString()); } return null; } private class LiquidReferenceSymbol implements IZenSymbol { + private final IEnvironmentGlobal environment; private final String name; - public LiquidReferenceSymbol(String name) { + public LiquidReferenceSymbol(IEnvironmentGlobal environment, String name) { + this.environment = environment; this.name = name; } @Override public IPartialExpression instance(ZenPosition position) { - JavaMethod method = JavaMethod.get( + IJavaMethod method = JavaMethod.get( GlobalRegistry.getTypeRegistry(), LiquidBracketHandler.class, "getLiquid", String.class); - return new ExpressionJavaCallStatic( + return new ExpressionCallStatic( position, + environment, method, new ExpressionString(position, name)); } diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/brackets/OreBracketHandler.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/brackets/OreBracketHandler.java index e3598e1..a64cc05 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/brackets/OreBracketHandler.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/brackets/OreBracketHandler.java @@ -12,11 +12,13 @@ import minetweaker.annotations.BracketHandler; import static minetweaker.api.minecraft.MineTweakerMC.getOreDict; import minetweaker.api.oredict.IOreDictEntry; import minetweaker.runtime.GlobalRegistry; -import stanhebben.zenscript.expression.ExpressionJavaCallStatic; +import stanhebben.zenscript.compiler.IEnvironmentGlobal; +import stanhebben.zenscript.expression.ExpressionCallStatic; import stanhebben.zenscript.expression.ExpressionString; import stanhebben.zenscript.expression.partial.IPartialExpression; import stanhebben.zenscript.parser.Token; import stanhebben.zenscript.symbols.IZenSymbol; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.ZenPosition; @@ -31,43 +33,46 @@ public class OreBracketHandler implements IBracketHandler { } @Override - public IZenSymbol resolve(List tokens) { + public IZenSymbol resolve(IEnvironmentGlobal environment, List tokens) { if (tokens.size() > 2) { if (tokens.get(0).getValue().equals("ore") && tokens.get(1).getValue().equals(":")) { - return find(tokens, 2, tokens.size()); + return find(environment, tokens, 2, tokens.size()); } } return null; } - private IZenSymbol find(List tokens, int startIndex, int endIndex) { + private IZenSymbol find(IEnvironmentGlobal environment, List tokens, int startIndex, int endIndex) { StringBuilder valueBuilder = new StringBuilder(); for (int i = startIndex; i < endIndex; i++) { Token token = tokens.get(i); valueBuilder.append(token.getValue()); } - return new OreReferenceSymbol(valueBuilder.toString()); + return new OreReferenceSymbol(environment, valueBuilder.toString()); } private class OreReferenceSymbol implements IZenSymbol { + private final IEnvironmentGlobal environment; private final String name; - public OreReferenceSymbol(String name) { + public OreReferenceSymbol(IEnvironmentGlobal environment, String name) { + this.environment = environment; this.name = name; } @Override public IPartialExpression instance(ZenPosition position) { - JavaMethod method = JavaMethod.get( + IJavaMethod method = JavaMethod.get( GlobalRegistry.getTypeRegistry(), OreBracketHandler.class, "getOre", String.class); - return new ExpressionJavaCallStatic( + return new ExpressionCallStatic( position, + environment, method, new ExpressionString(position, name)); } diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/player/MCPlayer.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/player/MCPlayer.java index 842e60f..99835c2 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/player/MCPlayer.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/player/MCPlayer.java @@ -94,6 +94,16 @@ public class MCPlayer implements IPlayer { return MineTweakerMC.getIItemStack(player.getCurrentEquippedItem()); } + @Override + public boolean isCreative() { + return player.capabilities.isCreativeMode; + } + + @Override + public boolean isAdventure() { + return !player.capabilities.allowEdit; + } + @Override public void openBrowser(String url) { if (player instanceof EntityPlayerMP) { diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/recipes/MCRecipeManager.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/recipes/MCRecipeManager.java index 14944ba..95c8355 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/recipes/MCRecipeManager.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/recipes/MCRecipeManager.java @@ -75,15 +75,13 @@ public class MCRecipeManager implements IRecipeManager { } @Override - public void addShaped(IItemStack output, IIngredient[][] ingredients, boolean mirrored) { - addShaped(output, ingredients, null, mirrored); + public void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function) { + addShaped(output, ingredients, null, false); } - + @Override - public void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function, boolean mirrored) { - ShapedRecipe recipe = new ShapedRecipe(output, ingredients, function, mirrored); - IRecipe irecipe = RecipeConverter.convert(recipe); - MineTweakerAPI.apply(new ActionAddRecipe(irecipe, recipe)); + public void addShapedMirrored(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function) { + addShaped(output, ingredients, null, true); } @Override @@ -383,4 +381,10 @@ public class MCRecipeManager implements IRecipeManager { return true; } + + private void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function, boolean mirrored) { + ShapedRecipe recipe = new ShapedRecipe(output, ingredients, function, mirrored); + IRecipe irecipe = RecipeConverter.convert(recipe); + MineTweakerAPI.apply(new ActionAddRecipe(irecipe, recipe)); + } } diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/server/ServerPlayer.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/server/ServerPlayer.java index 854a56f..53dbabd 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/server/ServerPlayer.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/server/ServerPlayer.java @@ -85,6 +85,16 @@ public class ServerPlayer implements IPlayer { return null; } + @Override + public boolean isCreative() { + return true; + } + + @Override + public boolean isAdventure() { + return false; + } + @Override public void openBrowser(String url) { if (Desktop.isDesktopSupported()) { diff --git a/MineTweaker3-MC164-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2BracketHandler.java b/MineTweaker3-MC164-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2BracketHandler.java index 21217ab..70d63a7 100644 --- a/MineTweaker3-MC164-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2BracketHandler.java +++ b/MineTweaker3-MC164-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2BracketHandler.java @@ -11,14 +11,15 @@ import static minetweaker.api.minecraft.MineTweakerMC.getIItemStack; import net.minecraft.item.ItemStack; import net.minecraftforge.oredict.OreDictionary; import stanhebben.zenscript.ZenTokener; +import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.expression.ExpressionInt; -import stanhebben.zenscript.expression.ExpressionJavaCallStatic; +import stanhebben.zenscript.expression.ExpressionCallStatic; import stanhebben.zenscript.expression.ExpressionString; import stanhebben.zenscript.expression.partial.IPartialExpression; import stanhebben.zenscript.parser.Token; import stanhebben.zenscript.symbols.IZenSymbol; import stanhebben.zenscript.type.ZenType; -import stanhebben.zenscript.type.natives.JavaMethod; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.util.ZenPosition; /** @@ -35,14 +36,14 @@ public class IC2BracketHandler implements IBracketHandler { return getIItemStack(stack); } - private final JavaMethod method; + private final IJavaMethod method; public IC2BracketHandler() { method = MineTweakerAPI.getJavaMethod(IC2BracketHandler.class, "getItem", String.class, int.class); } @Override - public IZenSymbol resolve(List tokens) { + public IZenSymbol resolve(IEnvironmentGlobal environment, List tokens) { if (tokens.size() >= 5) { if (tokens.get(0).getValue().equals("ic2") && tokens.get(1).getValue().equals("-") @@ -64,7 +65,7 @@ public class IC2BracketHandler implements IBracketHandler { MineTweakerAPI.logError("Not a valid IC2 item: " + name); return null; } else { - return new ItemReferenceSymbol(name, meta); + return new ItemReferenceSymbol(environment, name, meta); } } else { return null; @@ -79,18 +80,21 @@ public class IC2BracketHandler implements IBracketHandler { // ############################# private class ItemReferenceSymbol implements IZenSymbol { + private final IEnvironmentGlobal environment; private final String name; private final int meta; - public ItemReferenceSymbol(String name, int meta) { + public ItemReferenceSymbol(IEnvironmentGlobal environment, String name, int meta) { + this.environment = environment; this.name = name; this.meta = meta; } @Override public IPartialExpression instance(ZenPosition position) { - return new ExpressionJavaCallStatic( + return new ExpressionCallStatic( position, + environment, method, new ExpressionString(position, name), new ExpressionInt(position, meta, ZenType.INT)); diff --git a/MineTweaker3-MC164-Mod-MFR/src/main/java/minetweaker/mods/mfr/machines/Harvester.java b/MineTweaker3-MC164-Mod-MFR/src/main/java/minetweaker/mods/mfr/machines/Harvester.java index 64f7455..0af4b28 100644 --- a/MineTweaker3-MC164-Mod-MFR/src/main/java/minetweaker/mods/mfr/machines/Harvester.java +++ b/MineTweaker3-MC164-Mod-MFR/src/main/java/minetweaker/mods/mfr/machines/Harvester.java @@ -133,39 +133,30 @@ public class Harvester { @Override public boolean canBeHarvested(World world, Map map, int x, int y, int z) { - System.out.println("canBeHarvested start"); - for (TweakerHarvestable harvestable : harvestables) { if (harvestable.block.matches(MineTweakerMC.getBlock(world, x, y, z))) return true; } - System.out.println("canBeHarvested end"); - return false; } @Override public List getDrops(World world, Random random, Map map, int x, int y, int z) { - System.out.println("getDrops start"); - IBlock block = MineTweakerMC.getBlock(world, x, y, z); for (TweakerHarvestable harvestable : harvestables) { if (harvestable.block.matches(block)) { if (harvestable.possibleDrops == null) { Block mcBlock = ((MCBlockDefinition) block.getDefinition()).getInternalBlock(); List result = mcBlock.getBlockDropped(world, x, y, z, block.getMeta(), 0); - //return Collections.EMPTY_LIST; - System.out.println("getDrops end"); return result; } else { List result = Arrays.asList(MineTweakerMC.getItemStacks(WeightedItemStack.pickRandomDrops(random, harvestable.possibleDrops))); - System.out.println("getDrops end"); return result; } } } - System.out.println("getDrops end"); + return Collections.EMPTY_LIST; } diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/brackets/ItemBracketHandler.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/brackets/ItemBracketHandler.java index 47a326a..7d2525a 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/brackets/ItemBracketHandler.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/brackets/ItemBracketHandler.java @@ -19,14 +19,15 @@ import static minetweaker.api.minecraft.MineTweakerMC.getIItemStackWildcardSize; import net.minecraft.item.Item; import net.minecraftforge.oredict.OreDictionary; import stanhebben.zenscript.ZenTokener; +import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.expression.ExpressionInt; -import stanhebben.zenscript.expression.ExpressionJavaCallStatic; +import stanhebben.zenscript.expression.ExpressionCallStatic; import stanhebben.zenscript.expression.ExpressionString; import stanhebben.zenscript.expression.partial.IPartialExpression; import stanhebben.zenscript.parser.Token; import stanhebben.zenscript.symbols.IZenSymbol; import stanhebben.zenscript.type.ZenType; -import stanhebben.zenscript.type.natives.JavaMethod; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.util.ZenPosition; /** @@ -55,7 +56,7 @@ public class ItemBracketHandler implements IBracketHandler { } private final IZenSymbol symbolAny; - private final JavaMethod method; + private final IJavaMethod method; public ItemBracketHandler() { symbolAny = MineTweakerAPI.getJavaStaticFieldSymbol(IngredientAny.class, "INSTANCE"); @@ -66,7 +67,7 @@ public class ItemBracketHandler implements IBracketHandler { } @Override - public IZenSymbol resolve(List tokens) { + public IZenSymbol resolve(IEnvironmentGlobal environment, List tokens) { // any symbol if (tokens.size() == 1 && tokens.get(0).getValue().equals("*")) { return symbolAny; @@ -95,10 +96,10 @@ public class ItemBracketHandler implements IBracketHandler { } } - return find(tokens, fromIndex, toIndex, meta); + return find(environment, tokens, fromIndex, toIndex, meta); } - private IZenSymbol find(List tokens, int startIndex, int endIndex, int meta) { + private IZenSymbol find(IEnvironmentGlobal environment, List tokens, int startIndex, int endIndex, int meta) { StringBuilder valueBuilder = new StringBuilder(); for (int i = startIndex; i < endIndex; i++) { Token token = tokens.get(i); @@ -107,25 +108,28 @@ public class ItemBracketHandler implements IBracketHandler { String itemName = valueBuilder.toString(); if (itemNames.containsKey(itemName)) { - return new ItemReferenceSymbol(itemName, meta); + return new ItemReferenceSymbol(environment, itemName, meta); } return null; } private class ItemReferenceSymbol implements IZenSymbol { + private final IEnvironmentGlobal environment; private final String name; private final int meta; - public ItemReferenceSymbol(String name, int meta) { + public ItemReferenceSymbol(IEnvironmentGlobal environment, String name, int meta) { + this.environment = environment; this.name = name; this.meta = meta; } @Override public IPartialExpression instance(ZenPosition position) { - return new ExpressionJavaCallStatic( + return new ExpressionCallStatic( position, + environment, method, new ExpressionString(position, name), new ExpressionInt(position, meta, ZenType.INT)); diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/brackets/LiquidBracketHandler.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/brackets/LiquidBracketHandler.java index 31fd751..421d0cb 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/brackets/LiquidBracketHandler.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/brackets/LiquidBracketHandler.java @@ -9,11 +9,13 @@ import minetweaker.runtime.GlobalRegistry; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; -import stanhebben.zenscript.expression.ExpressionJavaCallStatic; +import stanhebben.zenscript.compiler.IEnvironmentGlobal; +import stanhebben.zenscript.expression.ExpressionCallStatic; import stanhebben.zenscript.expression.ExpressionString; import stanhebben.zenscript.expression.partial.IPartialExpression; import stanhebben.zenscript.parser.Token; import stanhebben.zenscript.symbols.IZenSymbol; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.ZenPosition; @@ -33,17 +35,17 @@ public class LiquidBracketHandler implements IBracketHandler { } @Override - public IZenSymbol resolve(List tokens) { + public IZenSymbol resolve(IEnvironmentGlobal environment, List tokens) { if (tokens.size() > 2) { if (tokens.get(0).getValue().equals("liquid") && tokens.get(1).getValue().equals(":")) { - return find(tokens, 2, tokens.size()); + return find(environment, tokens, 2, tokens.size()); } } return null; } - private IZenSymbol find(List tokens, int startIndex, int endIndex) { + private IZenSymbol find(IEnvironmentGlobal environment, List tokens, int startIndex, int endIndex) { StringBuilder valueBuilder = new StringBuilder(); for (int i = startIndex; i < endIndex; i++) { Token token = tokens.get(i); @@ -52,29 +54,32 @@ public class LiquidBracketHandler implements IBracketHandler { Fluid fluid = FluidRegistry.getFluid(valueBuilder.toString()); if (fluid != null) { - return new LiquidReferenceSymbol(valueBuilder.toString()); + return new LiquidReferenceSymbol(environment, valueBuilder.toString()); } return null; } private class LiquidReferenceSymbol implements IZenSymbol { + private final IEnvironmentGlobal environment; private final String name; - public LiquidReferenceSymbol(String name) { + public LiquidReferenceSymbol(IEnvironmentGlobal environment, String name) { + this.environment = environment; this.name = name; } @Override public IPartialExpression instance(ZenPosition position) { - JavaMethod method = JavaMethod.get( + IJavaMethod method = JavaMethod.get( GlobalRegistry.getTypeRegistry(), LiquidBracketHandler.class, "getLiquid", String.class); - return new ExpressionJavaCallStatic( + return new ExpressionCallStatic( position, + environment, method, new ExpressionString(position, name)); } diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/brackets/OreBracketHandler.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/brackets/OreBracketHandler.java index b4151f3..ad5c021 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/brackets/OreBracketHandler.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/brackets/OreBracketHandler.java @@ -12,11 +12,13 @@ import minetweaker.annotations.BracketHandler; import minetweaker.mc1710.oredict.MCOreDictEntry; import minetweaker.api.oredict.IOreDictEntry; import minetweaker.runtime.GlobalRegistry; -import stanhebben.zenscript.expression.ExpressionJavaCallStatic; +import stanhebben.zenscript.compiler.IEnvironmentGlobal; +import stanhebben.zenscript.expression.ExpressionCallStatic; import stanhebben.zenscript.expression.ExpressionString; import stanhebben.zenscript.expression.partial.IPartialExpression; import stanhebben.zenscript.parser.Token; import stanhebben.zenscript.symbols.IZenSymbol; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.ZenPosition; @@ -31,43 +33,46 @@ public class OreBracketHandler implements IBracketHandler { } @Override - public IZenSymbol resolve(List tokens) { + public IZenSymbol resolve(IEnvironmentGlobal environment, List tokens) { if (tokens.size() > 2) { if (tokens.get(0).getValue().equals("ore") && tokens.get(1).getValue().equals(":")) { - return find(tokens, 2, tokens.size()); + return find(environment, tokens, 2, tokens.size()); } } return null; } - private IZenSymbol find(List tokens, int startIndex, int endIndex) { + private IZenSymbol find(IEnvironmentGlobal environment, List tokens, int startIndex, int endIndex) { StringBuilder valueBuilder = new StringBuilder(); for (int i = startIndex; i < endIndex; i++) { Token token = tokens.get(i); valueBuilder.append(token.getValue()); } - return new OreReferenceSymbol(valueBuilder.toString()); + return new OreReferenceSymbol(environment, valueBuilder.toString()); } private class OreReferenceSymbol implements IZenSymbol { + private final IEnvironmentGlobal environment; private final String name; - public OreReferenceSymbol(String name) { + public OreReferenceSymbol(IEnvironmentGlobal environment, String name) { + this.environment = environment; this.name = name; } @Override public IPartialExpression instance(ZenPosition position) { - JavaMethod method = JavaMethod.get( + IJavaMethod method = JavaMethod.get( GlobalRegistry.getTypeRegistry(), OreBracketHandler.class, "getOre", String.class); - return new ExpressionJavaCallStatic( + return new ExpressionCallStatic( position, + environment, method, new ExpressionString(position, name)); } diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/player/MCPlayer.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/player/MCPlayer.java index 50e3afa..2445c0c 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/player/MCPlayer.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/player/MCPlayer.java @@ -95,6 +95,16 @@ public class MCPlayer implements IPlayer { return MineTweakerMC.getIItemStack(player.getCurrentEquippedItem()); } + @Override + public boolean isCreative() { + return player.capabilities.isCreativeMode; + } + + @Override + public boolean isAdventure() { + return !player.capabilities.allowEdit; + } + @Override public void openBrowser(String url) { if (player instanceof EntityPlayerMP) { diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/recipes/MCRecipeManager.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/recipes/MCRecipeManager.java index 54d1c59..07cd636 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/recipes/MCRecipeManager.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/recipes/MCRecipeManager.java @@ -75,15 +75,13 @@ public class MCRecipeManager implements IRecipeManager { } @Override - public void addShaped(IItemStack output, IIngredient[][] ingredients, boolean mirrored) { - addShaped(output, ingredients, null, mirrored); + public void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function) { + addShaped(output, ingredients, function, false); } @Override - public void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function, boolean mirrored) { - ShapedRecipe recipe = new ShapedRecipe(output, ingredients, function, mirrored); - IRecipe irecipe = RecipeConverter.convert(recipe); - MineTweakerAPI.apply(new ActionAddRecipe(irecipe, recipe)); + public void addShapedMirrored(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function) { + addShaped(output, ingredients, function, true); } @Override @@ -365,6 +363,12 @@ public class MCRecipeManager implements IRecipeManager { return null; } } + + private void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function, boolean mirrored) { + ShapedRecipe recipe = new ShapedRecipe(output, ingredients, function, mirrored); + IRecipe irecipe = RecipeConverter.convert(recipe); + MineTweakerAPI.apply(new ActionAddRecipe(irecipe, recipe)); + } private static boolean matches(Object input, IIngredient ingredient) { if ((input == null) != (ingredient == null)) { diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/server/ServerPlayer.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/server/ServerPlayer.java index 258f5b1..fc5ddaf 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/server/ServerPlayer.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/server/ServerPlayer.java @@ -86,6 +86,16 @@ public class ServerPlayer implements IPlayer { return null; } + @Override + public boolean isCreative() { + return true; + } + + @Override + public boolean isAdventure() { + return false; + } + @Override public void openBrowser(String url) { if (Desktop.isDesktopSupported()) { diff --git a/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2BracketHandler.java b/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2BracketHandler.java index 8e96533..b8f842a 100644 --- a/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2BracketHandler.java +++ b/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2BracketHandler.java @@ -11,14 +11,15 @@ import static minetweaker.api.minecraft.MineTweakerMC.getIItemStack; import net.minecraft.item.ItemStack; import net.minecraftforge.oredict.OreDictionary; import stanhebben.zenscript.ZenTokener; +import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.expression.ExpressionInt; -import stanhebben.zenscript.expression.ExpressionJavaCallStatic; +import stanhebben.zenscript.expression.ExpressionCallStatic; import stanhebben.zenscript.expression.ExpressionString; import stanhebben.zenscript.expression.partial.IPartialExpression; import stanhebben.zenscript.parser.Token; import stanhebben.zenscript.symbols.IZenSymbol; import stanhebben.zenscript.type.ZenType; -import stanhebben.zenscript.type.natives.JavaMethod; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.util.ZenPosition; /** @@ -35,14 +36,14 @@ public class IC2BracketHandler implements IBracketHandler { return getIItemStack(stack); } - private final JavaMethod method; + private final IJavaMethod method; public IC2BracketHandler() { method = MineTweakerAPI.getJavaMethod(IC2BracketHandler.class, "getItem", String.class, int.class); } @Override - public IZenSymbol resolve(List tokens) { + public IZenSymbol resolve(IEnvironmentGlobal environment, List tokens) { if (tokens.size() >= 5) { if (tokens.get(0).getValue().equals("ic2") && tokens.get(1).getValue().equals("-") @@ -64,7 +65,7 @@ public class IC2BracketHandler implements IBracketHandler { MineTweakerAPI.logError("Not a valid IC2 item: " + name); return null; } else { - return new ItemReferenceSymbol(name, meta); + return new ItemReferenceSymbol(environment, name, meta); } } else { return null; @@ -79,18 +80,21 @@ public class IC2BracketHandler implements IBracketHandler { // ############################# private class ItemReferenceSymbol implements IZenSymbol { + private final IEnvironmentGlobal environment; private final String name; private final int meta; - public ItemReferenceSymbol(String name, int meta) { + public ItemReferenceSymbol(IEnvironmentGlobal environment, String name, int meta) { + this.environment = environment; this.name = name; this.meta = meta; } @Override public IPartialExpression instance(ZenPosition position) { - return new ExpressionJavaCallStatic( + return new ExpressionCallStatic( position, + environment, method, new ExpressionString(position, name), new ExpressionInt(position, meta, ZenType.INT)); diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/brackets/ItemBracketHandler.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/brackets/ItemBracketHandler.java index 27f89b0..3aa0540 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/brackets/ItemBracketHandler.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/brackets/ItemBracketHandler.java @@ -19,14 +19,15 @@ import static minetweaker.api.minecraft.MineTweakerMC.getIItemStackWildcardSize; import net.minecraft.item.Item; import net.minecraftforge.oredict.OreDictionary; import stanhebben.zenscript.ZenTokener; +import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.expression.ExpressionInt; -import stanhebben.zenscript.expression.ExpressionJavaCallStatic; +import stanhebben.zenscript.expression.ExpressionCallStatic; import stanhebben.zenscript.expression.ExpressionString; import stanhebben.zenscript.expression.partial.IPartialExpression; import stanhebben.zenscript.parser.Token; import stanhebben.zenscript.symbols.IZenSymbol; import stanhebben.zenscript.type.ZenType; -import stanhebben.zenscript.type.natives.JavaMethod; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.util.ZenPosition; /** @@ -55,7 +56,7 @@ public class ItemBracketHandler implements IBracketHandler { } private final IZenSymbol symbolAny; - private final JavaMethod method; + private final IJavaMethod method; public ItemBracketHandler() { symbolAny = MineTweakerAPI.getJavaStaticFieldSymbol(IngredientAny.class, "INSTANCE"); @@ -66,7 +67,7 @@ public class ItemBracketHandler implements IBracketHandler { } @Override - public IZenSymbol resolve(List tokens) { + public IZenSymbol resolve(IEnvironmentGlobal environment, List tokens) { // any symbol if (tokens.size() == 1 && tokens.get(0).getValue().equals("*")) { return symbolAny; @@ -95,10 +96,10 @@ public class ItemBracketHandler implements IBracketHandler { } } - return find(tokens, fromIndex, toIndex, meta); + return find(environment, tokens, fromIndex, toIndex, meta); } - private IZenSymbol find(List tokens, int startIndex, int endIndex, int meta) { + private IZenSymbol find(IEnvironmentGlobal environment, List tokens, int startIndex, int endIndex, int meta) { StringBuilder valueBuilder = new StringBuilder(); for (int i = startIndex; i < endIndex; i++) { Token token = tokens.get(i); @@ -107,25 +108,28 @@ public class ItemBracketHandler implements IBracketHandler { String itemName = valueBuilder.toString(); if (itemNames.containsKey(itemName)) { - return new ItemReferenceSymbol(itemName, meta); + return new ItemReferenceSymbol(environment, itemName, meta); } return null; } private class ItemReferenceSymbol implements IZenSymbol { + private final IEnvironmentGlobal environment; private final String name; private final int meta; - public ItemReferenceSymbol(String name, int meta) { + public ItemReferenceSymbol(IEnvironmentGlobal environment, String name, int meta) { + this.environment = environment; this.name = name; this.meta = meta; } @Override public IPartialExpression instance(ZenPosition position) { - return new ExpressionJavaCallStatic( + return new ExpressionCallStatic( position, + environment, method, new ExpressionString(position, name), new ExpressionInt(position, meta, ZenType.INT)); diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/brackets/LiquidBracketHandler.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/brackets/LiquidBracketHandler.java index 0f6206e..4df20de 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/brackets/LiquidBracketHandler.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/brackets/LiquidBracketHandler.java @@ -9,11 +9,13 @@ import minetweaker.runtime.GlobalRegistry; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; -import stanhebben.zenscript.expression.ExpressionJavaCallStatic; +import stanhebben.zenscript.compiler.IEnvironmentGlobal; +import stanhebben.zenscript.expression.ExpressionCallStatic; import stanhebben.zenscript.expression.ExpressionString; import stanhebben.zenscript.expression.partial.IPartialExpression; import stanhebben.zenscript.parser.Token; import stanhebben.zenscript.symbols.IZenSymbol; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.ZenPosition; @@ -33,17 +35,17 @@ public class LiquidBracketHandler implements IBracketHandler { } @Override - public IZenSymbol resolve(List tokens) { + public IZenSymbol resolve(IEnvironmentGlobal environment, List tokens) { if (tokens.size() > 2) { if (tokens.get(0).getValue().equals("liquid") && tokens.get(1).getValue().equals(":")) { - return find(tokens, 2, tokens.size()); + return find(environment, tokens, 2, tokens.size()); } } return null; } - private IZenSymbol find(List tokens, int startIndex, int endIndex) { + private IZenSymbol find(IEnvironmentGlobal environment, List tokens, int startIndex, int endIndex) { StringBuilder valueBuilder = new StringBuilder(); for (int i = startIndex; i < endIndex; i++) { Token token = tokens.get(i); @@ -52,29 +54,32 @@ public class LiquidBracketHandler implements IBracketHandler { Fluid fluid = FluidRegistry.getFluid(valueBuilder.toString()); if (fluid != null) { - return new LiquidReferenceSymbol(valueBuilder.toString()); + return new LiquidReferenceSymbol(environment, valueBuilder.toString()); } return null; } private class LiquidReferenceSymbol implements IZenSymbol { + private final IEnvironmentGlobal environment; private final String name; - public LiquidReferenceSymbol(String name) { + public LiquidReferenceSymbol(IEnvironmentGlobal environment, String name) { + this.environment = environment; this.name = name; } @Override public IPartialExpression instance(ZenPosition position) { - JavaMethod method = JavaMethod.get( + IJavaMethod method = JavaMethod.get( GlobalRegistry.getTypeRegistry(), LiquidBracketHandler.class, "getLiquid", String.class); - return new ExpressionJavaCallStatic( + return new ExpressionCallStatic( position, + environment, method, new ExpressionString(position, name)); } diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/brackets/OreBracketHandler.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/brackets/OreBracketHandler.java index b055d86..99ffa4e 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/brackets/OreBracketHandler.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/brackets/OreBracketHandler.java @@ -12,12 +12,13 @@ import minetweaker.MineTweakerAPI; import minetweaker.annotations.BracketHandler; import static minetweaker.api.minecraft.MineTweakerMC.getOreDict; import minetweaker.api.oredict.IOreDictEntry; -import stanhebben.zenscript.expression.ExpressionJavaCallStatic; +import stanhebben.zenscript.compiler.IEnvironmentGlobal; +import stanhebben.zenscript.expression.ExpressionCallStatic; import stanhebben.zenscript.expression.ExpressionString; import stanhebben.zenscript.expression.partial.IPartialExpression; import stanhebben.zenscript.parser.Token; import stanhebben.zenscript.symbols.IZenSymbol; -import stanhebben.zenscript.type.natives.JavaMethod; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.util.ZenPosition; /** @@ -31,42 +32,45 @@ public class OreBracketHandler implements IBracketHandler { } @Override - public IZenSymbol resolve(List tokens) { + public IZenSymbol resolve(IEnvironmentGlobal environment, List tokens) { if (tokens.size() > 2) { if (tokens.get(0).getValue().equals("ore") && tokens.get(1).getValue().equals(":")) { - return find(tokens, 2, tokens.size()); + return find(environment, tokens, 2, tokens.size()); } } return null; } - private IZenSymbol find(List tokens, int startIndex, int endIndex) { + private IZenSymbol find(IEnvironmentGlobal environment, List tokens, int startIndex, int endIndex) { StringBuilder valueBuilder = new StringBuilder(); for (int i = startIndex; i < endIndex; i++) { Token token = tokens.get(i); valueBuilder.append(token.getValue()); } - return new OreReferenceSymbol(valueBuilder.toString()); + return new OreReferenceSymbol(environment, valueBuilder.toString()); } private class OreReferenceSymbol implements IZenSymbol { + private final IEnvironmentGlobal environment; private final String name; - public OreReferenceSymbol(String name) { + public OreReferenceSymbol(IEnvironmentGlobal environment, String name) { + this.environment = environment; this.name = name; } @Override public IPartialExpression instance(ZenPosition position) { - JavaMethod method = MineTweakerAPI.getJavaMethod( + IJavaMethod method = MineTweakerAPI.getJavaMethod( OreBracketHandler.class, "getOre", String.class); - return new ExpressionJavaCallStatic( + return new ExpressionCallStatic( position, + environment, method, new ExpressionString(position, name)); } diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/player/MCPlayer.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/player/MCPlayer.java index b107170..cd70ab2 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/player/MCPlayer.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/player/MCPlayer.java @@ -96,6 +96,16 @@ public class MCPlayer implements IPlayer { return MineTweakerMC.getIItemStack(player.getCurrentEquippedItem()); } + @Override + public boolean isCreative() { + return player.capabilities.isCreativeMode; + } + + @Override + public boolean isAdventure() { + return !player.capabilities.allowEdit; + } + @Override public void openBrowser(String url) { if (player instanceof EntityPlayerMP) { diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/recipes/MCRecipeManager.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/recipes/MCRecipeManager.java index 5b9152c..d100f6d 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/recipes/MCRecipeManager.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/recipes/MCRecipeManager.java @@ -73,17 +73,15 @@ public class MCRecipeManager implements IRecipeManager { MineTweakerAPI.apply(new ActionRemoveRecipes(toRemove, removeIndex)); return toRemove.size(); } - + @Override - public void addShaped(IItemStack output, IIngredient[][] ingredients, boolean mirrored) { - addShaped(output, ingredients, null, mirrored); + public void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function) { + addShaped(output, ingredients, function, false); } @Override - public void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function, boolean mirrored) { - ShapedRecipe recipe = new ShapedRecipe(output, ingredients, function, mirrored); - IRecipe irecipe = RecipeConverter.convert(recipe); - MineTweakerAPI.apply(new ActionAddRecipe(irecipe, recipe)); + public void addShapedMirrored(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function) { + addShaped(output, ingredients, function, true); } @Override @@ -383,4 +381,10 @@ public class MCRecipeManager implements IRecipeManager { return true; } + + private void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function, boolean mirrored) { + ShapedRecipe recipe = new ShapedRecipe(output, ingredients, function, mirrored); + IRecipe irecipe = RecipeConverter.convert(recipe); + MineTweakerAPI.apply(new ActionAddRecipe(irecipe, recipe)); + } } diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/server/ServerPlayer.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/server/ServerPlayer.java index 3671e5c..13526f5 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/server/ServerPlayer.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/server/ServerPlayer.java @@ -86,6 +86,16 @@ public class ServerPlayer implements IPlayer { return null; } + @Override + public boolean isCreative() { + return true; + } + + @Override + public boolean isAdventure() { + return false; + } + @Override public void openBrowser(String url) { if (Desktop.isDesktopSupported()) { diff --git a/ZenScript/src/main/java/stanhebben/zenscript/IZenCompileEnvironment.java b/ZenScript/src/main/java/stanhebben/zenscript/IZenCompileEnvironment.java index bb6b29d..2035011 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/IZenCompileEnvironment.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/IZenCompileEnvironment.java @@ -7,8 +7,7 @@ package stanhebben.zenscript; import java.util.List; -import stanhebben.zenscript.IZenErrorLogger; -import stanhebben.zenscript.TypeExpansion; +import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.TypeRegistry; import stanhebben.zenscript.parser.Token; import stanhebben.zenscript.symbols.IZenSymbol; @@ -24,7 +23,7 @@ public interface IZenCompileEnvironment { public IZenSymbol getDollar(String name); - public IZenSymbol getBracketed(List tokens); + public IZenSymbol getBracketed(IEnvironmentGlobal environment, List tokens); public TypeRegistry getTypeRegistry(); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/TypeExpansion.java b/ZenScript/src/main/java/stanhebben/zenscript/TypeExpansion.java index 282e538..22108a5 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/TypeExpansion.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/TypeExpansion.java @@ -17,16 +17,21 @@ import stanhebben.zenscript.annotations.ZenMethodStatic; import stanhebben.zenscript.annotations.ZenOperator; import stanhebben.zenscript.annotations.ZenSetter; import stanhebben.zenscript.compiler.IEnvironmentGlobal; +import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.compiler.ITypeRegistry; import stanhebben.zenscript.expression.Expression; +import stanhebben.zenscript.expression.ExpressionCallStatic; import stanhebben.zenscript.expression.partial.IPartialExpression; import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; import stanhebben.zenscript.type.expand.ZenExpandCaster; import stanhebben.zenscript.type.expand.ZenExpandMember; import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.type.natives.ZenNativeOperator; import stanhebben.zenscript.util.MethodOutput; import stanhebben.zenscript.util.ZenPosition; +import static stanhebben.zenscript.util.ZenTypeUtil.signature; +import stanhebben.zenscript.value.IAny; /** * Type expansions provide additional members for existing types. They can @@ -77,7 +82,7 @@ public class TypeExpansion { for (Annotation annotation : method.getAnnotations()) { if (annotation instanceof ZenCaster) { checkStatic(method); - casters.add(new ZenExpandCaster(new JavaMethod(cls, method, types))); + casters.add(new ZenExpandCaster(new JavaMethod(method, types))); } else if (annotation instanceof ZenGetter) { checkStatic(method); ZenGetter getterAnnotation = (ZenGetter) annotation; @@ -86,7 +91,7 @@ public class TypeExpansion { if (!members.containsKey(name)) { members.put(name, new ZenExpandMember(type, name)); } - members.get(name).setGetter(new JavaMethod(cls, method, types)); + members.get(name).setGetter(new JavaMethod(method, types)); } else if (annotation instanceof ZenSetter) { checkStatic(method); ZenSetter setterAnnotation = (ZenSetter) annotation; @@ -95,7 +100,7 @@ public class TypeExpansion { if (!members.containsKey(name)) { members.put(name, new ZenExpandMember(type, name)); } - members.get(name).setSetter(new JavaMethod(cls, method, types)); + members.get(name).setSetter(new JavaMethod(method, types)); } else if (annotation instanceof ZenOperator) { checkStatic(method); ZenOperator operatorAnnotation = (ZenOperator) annotation; @@ -107,7 +112,7 @@ public class TypeExpansion { } else { unaryOperators.add(new ZenNativeOperator( operatorAnnotation.value(), - new JavaMethod(cls, method, types))); + new JavaMethod(method, types))); } break; case ADD: @@ -128,7 +133,7 @@ public class TypeExpansion { } else { binaryOperators.add(new ZenNativeOperator( operatorAnnotation.value(), - new JavaMethod(cls, method, types))); + new JavaMethod(method, types))); } break; case INDEXSET: @@ -137,7 +142,7 @@ public class TypeExpansion { } else { trinaryOperators.add(new ZenNativeOperator( operatorAnnotation.value(), - new JavaMethod(cls, method, types))); + new JavaMethod(method, types))); } break; } @@ -150,7 +155,7 @@ public class TypeExpansion { if (!members.containsKey(methodName)) { members.put(methodName, new ZenExpandMember(type, methodName)); } - members.get(methodName).addMethod(new JavaMethod(cls, method, types)); + members.get(methodName).addMethod(new JavaMethod(method, types)); } else if (annotation instanceof ZenMethodStatic) { checkStatic(method); ZenMethodStatic methodAnnotation = (ZenMethodStatic) annotation; @@ -160,12 +165,24 @@ public class TypeExpansion { if (!staticMembers.containsKey(methodName)) { staticMembers.put(methodName, new ZenExpandMember(type, methodName)); } - staticMembers.get(methodName).addMethod(new JavaMethod(cls, method, types)); + staticMembers.get(methodName).addMethod(new JavaMethod(method, types)); } } } } + /** + * Registers all casting rules to the given delegate. + * + * @param environment compilation environment + * @param rules target delegate + */ + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules) { + for (ZenExpandCaster caster : casters) { + caster.constructCastingRules(environment, rules); + } + } + /** * Retrieves a caster from this expansion. May return null if no suitable * caster was available. @@ -209,7 +226,7 @@ public class TypeExpansion { OperatorType operator) { for (ZenNativeOperator op : unaryOperators) { if (op.getOperator() == operator) { - return op.getMethod().callStatic(position, environment, value); + return new ExpressionCallStatic(position, environment, op.getMethod(), value); } } @@ -235,7 +252,7 @@ public class TypeExpansion { OperatorType operator) { for (ZenNativeOperator op : binaryOperators) { if (op.getOperator() == operator) { - return op.getMethod().callStatic(position, environment, left, right); + return new ExpressionCallStatic(position, environment, op.getMethod(), left, right); } } @@ -263,7 +280,7 @@ public class TypeExpansion { OperatorType operator) { for (ZenNativeOperator op : trinaryOperators) { if (op.getOperator() == operator) { - return op.getMethod().callStatic(position, environment, first, second, third); + return new ExpressionCallStatic(position, environment, op.getMethod(), first, second, third); } } @@ -312,6 +329,7 @@ public class TypeExpansion { public void compileAnyCast(ZenType type, MethodOutput output, IEnvironmentGlobal environment, int localValue, int localClass) { if (type == null) throw new IllegalArgumentException("type cannot be null"); + Type asmType = type.toASMType(); if (asmType == null) { throw new RuntimeException("type has no asm type"); @@ -340,7 +358,8 @@ public class TypeExpansion { output.ifEQ(skip); output.load(type.toASMType(), localValue); caster.compile(output); - output.invokeStatic(casterAny, "rtAs", "(Ljava/lang/Class;)Z"); + output.loadObject(localClass); + output.invokeStatic(casterAny, "rtAs", "(" + caster.getTarget().getSignature() + "Ljava/lang/Class;)Ljava/lang/Object;"); output.returnType(caster.getTarget().toASMType()); output.label(skip); } @@ -374,6 +393,25 @@ public class TypeExpansion { } } + public boolean compileAnyUnary(MethodOutput output, OperatorType type, IEnvironmentMethod environment) { + for (ZenNativeOperator operator : unaryOperators) { + if (operator.getOperator() == type) { + ZenType returnType = operator.getMethod().getReturnType(); + + output.loadObject(0); + operator.getMethod().invokeStatic(output); + output.invokeStatic( + returnType.getAnyClassName(environment), + "valueOf", + "(" + returnType.getSignature() + ")" + ZenType.ANY.getSignature()); + output.returnObject(); + return true; + } + } + + return false; + } + // ####################### // ### Private methods ### // ####################### diff --git a/ZenScript/src/main/java/stanhebben/zenscript/ZenModule.java b/ZenScript/src/main/java/stanhebben/zenscript/ZenModule.java index bf6f102..9ec7582 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/ZenModule.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/ZenModule.java @@ -50,8 +50,9 @@ public class ZenModule { * @param mainFileName main filename (used for debug info) * @param scripts scripts to compile * @param environmentGlobal global compile environment + * @param debug enable debug mode (outputs classes to generated directory) */ - public static void compileScripts(String mainFileName, List scripts, IEnvironmentGlobal environmentGlobal) { + public static void compileScripts(String mainFileName, List scripts, IEnvironmentGlobal environmentGlobal, boolean debug) { ClassWriter clsMain = new ClassWriter(ClassWriter.COMPUTE_FRAMES); clsMain.visitSource(mainFileName, null); @@ -117,6 +118,7 @@ public class ZenModule { if (script.getStatements().size() > 0) { MethodOutput scriptOutput = new MethodOutput(clsScript, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "__script__", "()V", null, null); IEnvironmentMethod functionMethod = new EnvironmentMethod(scriptOutput, environmentScript); + //scriptOutput.enableDebug(); scriptOutput.start(); for (Statement statement : script.getStatements()) { statement.compile(functionMethod); @@ -143,6 +145,28 @@ public class ZenModule { constructor.visitMaxs(0, 0); constructor.visitEnd(); + // debug: output classes + if (debug) { + try { + File outputDir = new File("generated"); + outputDir.mkdir(); + + for (String className : environmentGlobal.getClassNames()) { + File outputFile = new File(outputDir, className.replace('.', '/') + ".class"); + + if (!outputFile.getParentFile().exists()) { + outputFile.getParentFile().mkdirs(); + } + + FileOutputStream output = new FileOutputStream(outputFile); + output.write(environmentGlobal.getClass(className)); + output.close(); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + } + environmentGlobal.putClass("__ZenMain__", clsMain.toByteArray()); } @@ -176,7 +200,7 @@ public class ZenModule { List files = new ArrayList(); files.add(file); - compileScripts(filename, files, environmentGlobal); + compileScripts(filename, files, environmentGlobal, false); // debug: output classes File outputDir = new File("generated"); @@ -238,18 +262,7 @@ public class ZenModule { } String filename = file.getName(); - compileScripts(filename, files, environmentGlobal); - - // debug: output classes - File outputDir = new File("generated"); - outputDir.mkdir(); - - for (Map.Entry entry : classes.entrySet()) { - File outputFile = new File(outputDir, entry.getKey().replace('.', '/') + ".class"); - FileOutputStream output = new FileOutputStream(outputFile); - output.write(entry.getValue()); - output.close(); - } + compileScripts(filename, files, environmentGlobal, true); return new ZenModule(classes, baseClassLoader); } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/ZenParsedFile.java b/ZenScript/src/main/java/stanhebben/zenscript/ZenParsedFile.java index 316e9c1..9d04f90 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/ZenParsedFile.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/ZenParsedFile.java @@ -126,7 +126,7 @@ public class ZenParsedFile { } functions.put(function.getName(), function); } else { - statements.add(Statement.read(tokener, environmentScript)); + statements.add(Statement.read(tokener, environmentScript, null)); } } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentClass.java b/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentClass.java index c1ce5c6..c2c6e4f 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentClass.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentClass.java @@ -9,6 +9,7 @@ package stanhebben.zenscript.compiler; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; +import java.util.Set; import org.objectweb.asm.ClassVisitor; import stanhebben.zenscript.TypeExpansion; import stanhebben.zenscript.expression.partial.IPartialExpression; @@ -90,4 +91,14 @@ public class EnvironmentClass implements IEnvironmentClass { public void warning(ZenPosition position, String message) { global.warning(position, message); } + + @Override + public Set getClassNames() { + return global.getClassNames(); + } + + @Override + public byte[] getClass(String name) { + return global.getClass(name); + } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentGlobal.java b/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentGlobal.java index 879d2a3..598059a 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentGlobal.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentGlobal.java @@ -9,6 +9,7 @@ package stanhebben.zenscript.compiler; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; +import java.util.Set; import stanhebben.zenscript.IZenErrorLogger; import stanhebben.zenscript.TypeExpansion; import stanhebben.zenscript.expression.partial.IPartialExpression; @@ -103,4 +104,14 @@ public class EnvironmentGlobal implements IEnvironmentGlobal { local.put(name, value); } } + + @Override + public Set getClassNames() { + return classes.keySet(); + } + + @Override + public byte[] getClass(String name) { + return classes.get(name); + } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentMethod.java b/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentMethod.java index 674b5d4..9feaf6c 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentMethod.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentMethod.java @@ -9,6 +9,7 @@ package stanhebben.zenscript.compiler; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; +import java.util.Set; import org.objectweb.asm.ClassVisitor; import stanhebben.zenscript.TypeExpansion; import stanhebben.zenscript.expression.partial.IPartialExpression; @@ -107,4 +108,14 @@ public class EnvironmentMethod implements IEnvironmentMethod { public void putValue(String name, IZenSymbol value) { local.put(name, value); } + + @Override + public Set getClassNames() { + return environment.getClassNames(); + } + + @Override + public byte[] getClass(String name) { + return environment.getClass(name); + } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentScope.java b/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentScope.java index b435c5e..478363d 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentScope.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentScope.java @@ -9,6 +9,7 @@ package stanhebben.zenscript.compiler; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; +import java.util.Set; import org.objectweb.asm.ClassVisitor; import stanhebben.zenscript.TypeExpansion; import stanhebben.zenscript.expression.partial.IPartialExpression; @@ -106,4 +107,14 @@ public class EnvironmentScope implements IEnvironmentMethod { public void warning(ZenPosition position, String message) { outer.warning(position, message); } + + @Override + public Set getClassNames() { + return outer.getClassNames(); + } + + @Override + public byte[] getClass(String name) { + return outer.getClass(name); + } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentScript.java b/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentScript.java index 54cb73e..6f87eeb 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentScript.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/compiler/EnvironmentScript.java @@ -9,6 +9,7 @@ package stanhebben.zenscript.compiler; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; +import java.util.Set; import stanhebben.zenscript.IZenCompileEnvironment; import stanhebben.zenscript.TypeExpansion; import stanhebben.zenscript.expression.partial.IPartialExpression; @@ -86,4 +87,14 @@ public class EnvironmentScript implements IEnvironmentGlobal { public void warning(ZenPosition position, String message) { parent.warning(position, message); } + + @Override + public Set getClassNames() { + return parent.getClassNames(); + } + + @Override + public byte[] getClass(String name) { + return parent.getClass(name); + } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/compiler/IEnvironmentGlobal.java b/ZenScript/src/main/java/stanhebben/zenscript/compiler/IEnvironmentGlobal.java index e5862a7..4ef94ce 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/compiler/IEnvironmentGlobal.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/compiler/IEnvironmentGlobal.java @@ -6,6 +6,7 @@ package stanhebben.zenscript.compiler; +import java.util.Set; import stanhebben.zenscript.IZenErrorLogger; import stanhebben.zenscript.TypeExpansion; import stanhebben.zenscript.expression.partial.IPartialExpression; @@ -26,6 +27,10 @@ public interface IEnvironmentGlobal extends ITypeRegistry, IZenErrorLogger { public boolean containsClass(String name); + public Set getClassNames(); + + public byte[] getClass(String name); + public void putClass(String name, byte[] data); public IPartialExpression getValue(String name, ZenPosition position); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/definitions/ParsedFunction.java b/ZenScript/src/main/java/stanhebben/zenscript/definitions/ParsedFunction.java index 3d0d1cc..56ef89c 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/definitions/ParsedFunction.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/definitions/ParsedFunction.java @@ -67,7 +67,7 @@ public class ParsedFunction { ArrayList statementsAL = new ArrayList(); while (parser.optional(T_ACLOSE) == null) { - statementsAL.add(Statement.read(parser, environment)); + statementsAL.add(Statement.read(parser, environment, type)); } statements = statementsAL.toArray(new Statement[statementsAL.size()]); } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/Expression.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/Expression.java index fa68103..7b64c0c 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/Expression.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/Expression.java @@ -8,13 +8,13 @@ import stanhebben.zenscript.expression.partial.IPartialExpression; import stanhebben.zenscript.parser.expression.ParsedExpression; import stanhebben.zenscript.symbols.IZenSymbol; import stanhebben.zenscript.type.ZenType; -import stanhebben.zenscript.type.ZenTypeBool; +import stanhebben.zenscript.type.casting.ICastingRule; import stanhebben.zenscript.util.ZenPosition; public abstract class Expression implements IPartialExpression { - public static final Expression parse(ZenTokener parser, IEnvironmentMethod environment) { + public static final Expression parse(ZenTokener parser, IEnvironmentMethod environment, ZenType predictedType) { return ParsedExpression.read(parser, environment) - .compile(environment) + .compile(environment, predictedType) .eval(environment); } @@ -28,13 +28,17 @@ public abstract class Expression implements IPartialExpression { return position; } - public abstract ZenType getType(); - public Expression cast(ZenPosition position, IEnvironmentGlobal environment, ZenType type) { if (getType() == type) { return this; } else { - return getType().cast(position, environment, this, type); + ICastingRule castingRule = getType().getCastingRule(type, environment); + if (castingRule == null) { + environment.error(position, "Cannot cast " + this.getType() + " to " + type); + return new ExpressionInvalid(position, type); + } else { + return new ExpressionAs(position, this, castingRule); + } } } @@ -77,6 +81,11 @@ public abstract class Expression implements IPartialExpression { return getType().call(position, environment, this, values); } + @Override + public ZenType[] predictCallTypes(int numArguments) { + return getType().predictCallTypes(numArguments); + } + @Override public IZenSymbol toSymbol() { return null; diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionArray.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionArray.java index 85a8c40..a51f0ca 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionArray.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionArray.java @@ -5,8 +5,8 @@ import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.type.ZenType; -import stanhebben.zenscript.type.ZenTypeAny; import stanhebben.zenscript.type.ZenTypeArrayBasic; +import stanhebben.zenscript.type.casting.ICastingRule; import stanhebben.zenscript.util.MethodOutput; import stanhebben.zenscript.util.ZenPosition; @@ -14,21 +14,19 @@ public class ExpressionArray extends Expression { private final Expression[] contents; private final ZenTypeArrayBasic type; - public ExpressionArray(ZenPosition position, Expression... contents) { + public ExpressionArray(ZenPosition position, ZenTypeArrayBasic type, Expression... contents) { super(position); - this.contents = contents; - type = new ZenTypeArrayBasic(ZenTypeAny.INSTANCE); - } - - public ExpressionArray(ZenPosition position, Expression[] contents, ZenTypeArrayBasic type) { - super(position); this.contents = contents; this.type = type; } @Override public Expression cast(ZenPosition position, IEnvironmentGlobal environment, ZenType type) { + if (this.type.equals(type)) { + return this; + } + if (type instanceof ZenTypeArrayBasic) { ZenTypeArrayBasic arrayType = (ZenTypeArrayBasic) type; Expression[] newContents = new Expression[contents.length]; @@ -36,12 +34,15 @@ public class ExpressionArray extends Expression { newContents[i] = contents[i].cast(position, environment, arrayType.getBaseType()); } - return new ExpressionArray(getPosition(), newContents, arrayType); - } else if (this.type.canCastImplicit(type, environment)) { - return this.type.cast(position, environment, this, type); + return new ExpressionArray(getPosition(), arrayType, newContents); } else { - environment.error(position, "cannot cast " + this.type + " to " + type); - return new ExpressionInvalid(position, type); + ICastingRule castingRule = this.type.getCastingRule(type, environment); + if (castingRule == null) { + environment.error(position, "cannot cast " + this.type + " to " + type); + return new ExpressionInvalid(position, type); + } else { + return new ExpressionAs(position, this, castingRule); + } } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionAs.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionAs.java index 10852c2..7bb989b 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionAs.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionAs.java @@ -3,34 +3,46 @@ package stanhebben.zenscript.expression; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.casting.ICastingRule; import stanhebben.zenscript.util.ZenPosition; public class ExpressionAs extends Expression { private final Expression value; - private final ZenType type; + private final ICastingRule castingRule; - public ExpressionAs(ZenPosition position, Expression value, ZenType type) { + public ExpressionAs(ZenPosition position, Expression value, ICastingRule castingRule) { super(position); this.value = value; - this.type = type; + this.castingRule = castingRule; } - @Override + /*@Override public Expression cast(ZenPosition position, IEnvironmentGlobal environment, ZenType type) { - return this.type.cast(position, environment, this, type); - } + if (castingRule.getResultingType().equals(type)) { + return this; + } + + ICastingRule newCastingRule = type.getCastingRule(type, environment); + if (newCastingRule == null) { + environment.error(position, "Cannot cast " + getType() + " to " + type); + return new ExpressionInvalid(position, type); + } else { + return new ExpressionAs(position, this, newCastingRule); + } + }*/ @Override public ZenType getType() { - return type; + return castingRule.getResultingType(); } @Override public void compile(boolean result, IEnvironmentMethod environment) { value.compile(result, environment); + if (result) { - value.getType().compileCast(getPosition(), environment, type); + castingRule.compile(environment); } } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionBool.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionBool.java index f3e44f4..278a32f 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionBool.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionBool.java @@ -30,7 +30,7 @@ public class ExpressionBool extends Expression { if (type == ZenType.BOOL) { return this; } else { - return ZenType.BOOL.cast(position, environment, this, type); + return super.cast(position, environment, type); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionJavaCallStatic.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionCallStatic.java similarity index 72% rename from ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionJavaCallStatic.java rename to ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionCallStatic.java index 8a06467..84e2b2a 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionJavaCallStatic.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionCallStatic.java @@ -6,8 +6,10 @@ package stanhebben.zenscript.expression; +import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.MethodOutput; import stanhebben.zenscript.util.ZenPosition; @@ -16,18 +18,19 @@ import stanhebben.zenscript.util.ZenPosition; * * @author Stanneke */ -public class ExpressionJavaCallStatic extends Expression { - private final JavaMethod method; +public class ExpressionCallStatic extends Expression { + private final IJavaMethod method; private final Expression[] arguments; - public ExpressionJavaCallStatic( + public ExpressionCallStatic( ZenPosition position, - JavaMethod method, + IEnvironmentGlobal environment, + IJavaMethod method, Expression... arguments) { super(position); this.method = method; - this.arguments = arguments; + this.arguments = JavaMethod.rematch(position, method, environment, arguments); } @Override @@ -43,7 +46,7 @@ public class ExpressionJavaCallStatic extends Expression { argument.compile(true, environment); } - output.invokeStatic(method); + method.invokeStatic(output); if (method.getReturnType() != ZenType.VOID && !result) { output.pop(method.getReturnType().isLarge()); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionJavaCallVirtual.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionCallVirtual.java similarity index 72% rename from ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionJavaCallVirtual.java rename to ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionCallVirtual.java index 8d42efa..caf818d 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionJavaCallVirtual.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionCallVirtual.java @@ -6,8 +6,10 @@ package stanhebben.zenscript.expression; +import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.ZenPosition; @@ -15,15 +17,16 @@ import stanhebben.zenscript.util.ZenPosition; * * @author Stanneke */ -public class ExpressionJavaCallVirtual extends Expression { - private final JavaMethod method; +public class ExpressionCallVirtual extends Expression { + private final IJavaMethod method; private final Expression receiver; private final Expression[] arguments; - public ExpressionJavaCallVirtual( + public ExpressionCallVirtual( ZenPosition position, - JavaMethod method, + IEnvironmentGlobal environment, + IJavaMethod method, Expression receiver, Expression... arguments) { super(position); @@ -31,7 +34,7 @@ public class ExpressionJavaCallVirtual extends Expression { this.method = method; this.receiver = receiver; - this.arguments = arguments; + this.arguments = JavaMethod.rematch(position, method, environment, arguments); } @Override @@ -47,7 +50,7 @@ public class ExpressionJavaCallVirtual extends Expression { argument.compile(true, environment); } - environment.getOutput().invoke(method); + method.invokeVirtual(environment.getOutput()); if (method.getReturnType() != ZenType.VOID && !result) { environment.getOutput().pop(method.getReturnType().isLarge()); } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionFunction.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionFunction.java index 8c04222..4da10b4 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionFunction.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionFunction.java @@ -25,11 +25,11 @@ import stanhebben.zenscript.util.ZenPosition; public class ExpressionFunction extends Expression { private final List arguments; private final ZenType returnType; - private final Statement[] statements; + private final List statements; private final ZenTypeFunction functionType; - public ExpressionFunction(ZenPosition position, List arguments, ZenType returnType, Statement[] statements) { + public ExpressionFunction(ZenPosition position, List arguments, ZenType returnType, List statements) { super(position); System.out.println("Function expression: " + arguments.size() + " arguments"); @@ -95,6 +95,7 @@ public class ExpressionFunction extends Expression { @Override public void compile(boolean result, IEnvironmentMethod environment) { // TODO: implement + // TODO: make sure the function is compiled properly throw new UnsupportedOperationException("not yet implemented"); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionInvalid.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionInvalid.java index 6b49f04..521eb57 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionInvalid.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionInvalid.java @@ -7,10 +7,8 @@ package stanhebben.zenscript.expression; import org.objectweb.asm.Label; -import stanhebben.zenscript.compiler.EnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; -import stanhebben.zenscript.compiler.EnvironmentMethod; import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.type.ZenTypeAny; import stanhebben.zenscript.util.ZenPosition; @@ -32,6 +30,8 @@ public class ExpressionInvalid extends Expression { super(position); this.type = type; + + //throw new RuntimeException("Constructing invalid expression"); } @Override diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionJavaCallStaticGenerated.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionJavaCallStaticGenerated.java deleted file mode 100644 index 6c4f62f..0000000 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionJavaCallStaticGenerated.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -package stanhebben.zenscript.expression; - -import stanhebben.zenscript.compiler.IEnvironmentMethod; -import stanhebben.zenscript.type.ZenType; -import stanhebben.zenscript.util.MethodOutput; -import stanhebben.zenscript.util.ZenPosition; - -/** - * - * @author Stanneke - */ -public class ExpressionJavaCallStaticGenerated extends Expression { - private final String target; - private final String name; - private final String descriptor; - - private final ZenType returnZType; - private final Expression[] arguments; - - public ExpressionJavaCallStaticGenerated( - ZenPosition position, - String target, String name, String descriptor, - ZenType returnZType, - Expression... arguments) { - super(position); - - this.target = target; - this.name = name; - this.descriptor = descriptor; - - this.returnZType = returnZType; - this.arguments = arguments; - } - - @Override - public ZenType getType() { - return returnZType; - } - - @Override - public void compile(boolean result, IEnvironmentMethod environment) { - MethodOutput output = environment.getOutput(); - - for (Expression argument : arguments) { - argument.compile(true, environment); - } - - output.invokeStatic(target, name, descriptor); - if (!descriptor.endsWith("V") && !result) { - output.pop(); - } - } -} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionJavaLambda.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionJavaLambda.java index 0ec7508..2a2b18e 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionJavaLambda.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionJavaLambda.java @@ -30,7 +30,7 @@ import static stanhebben.zenscript.util.ZenTypeUtil.internal; public class ExpressionJavaLambda extends Expression { private final Class interfaceClass; private final List arguments; - private final Statement[] statements; + private final List statements; private final ZenType type; @@ -38,7 +38,7 @@ public class ExpressionJavaLambda extends Expression { ZenPosition position, Class interfaceClass, List arguments, - Statement[] statements, + List statements, ZenType type) { super(position); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionTable.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionMap.java similarity index 68% rename from ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionTable.java rename to ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionMap.java index 71ad385..b2abbd2 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionTable.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionMap.java @@ -7,25 +7,17 @@ import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.type.ZenTypeAny; import stanhebben.zenscript.type.ZenTypeAssociative; +import stanhebben.zenscript.type.casting.ICastingRule; import stanhebben.zenscript.util.MethodOutput; import stanhebben.zenscript.util.ZenPosition; import static stanhebben.zenscript.util.ZenTypeUtil.internal; -public class ExpressionTable extends Expression { +public class ExpressionMap extends Expression { private final Expression[] keys; private final Expression[] values; private final ZenTypeAssociative type; - public ExpressionTable(ZenPosition position, Expression[] keys, Expression[] values) { - super(position); - - this.keys = keys; - this.values = values; - - type = new ZenTypeAssociative(ZenTypeAny.INSTANCE, ZenTypeAny.INSTANCE); - } - - public ExpressionTable(ZenPosition position, Expression[] keys, Expression[] values, ZenTypeAssociative type) { + public ExpressionMap(ZenPosition position, Expression[] keys, Expression[] values, ZenTypeAssociative type) { super(position); this.keys = keys; @@ -69,22 +61,29 @@ public class ExpressionTable extends Expression { @Override public Expression cast(ZenPosition position, IEnvironmentGlobal environment, ZenType type) { + if (this.type.equals(type)) { + return this; + } + if (type instanceof ZenTypeAssociative) { - ZenTypeAssociative keyType = (ZenTypeAssociative) type; + ZenTypeAssociative associativeType = (ZenTypeAssociative) type; Expression[] newKeys = new Expression[keys.length]; Expression[] newValues = new Expression[values.length]; for (int i = 0; i < keys.length; i++) { - newKeys[i] = keys[i].cast(position, environment, keyType.getKeyType()); - newValues[i] = values[i].cast(position, environment, keyType.getValueType()); + newKeys[i] = keys[i].cast(position, environment, associativeType.getKeyType()); + newValues[i] = values[i].cast(position, environment, associativeType.getValueType()); } - return new ExpressionTable(getPosition(), newKeys, newValues, keyType); - } else if (this.type.canCastImplicit(type, environment)) { - return this.type.cast(position, environment, this, type); + return new ExpressionMap(getPosition(), newKeys, newValues, associativeType); } else { - environment.error(position, "cannot cast " + this.type + " to " + type); - return new ExpressionInvalid(position, type); + ICastingRule castingRule = this.type.getCastingRule(type, environment); + if (castingRule == null) { + environment.error(position, "cannot cast " + this.type + " to " + type); + return new ExpressionInvalid(position, type); + } else { + return new ExpressionAs(position, this, castingRule); + } } } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionOrOr.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionOrOr.java index a741012..4af7522 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionOrOr.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionOrOr.java @@ -17,7 +17,7 @@ public class ExpressionOrOr extends Expression { @Override public ZenType getType() { - return a.getType(); // TODO: combine both types + return a.getType(); } @Override diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/IPartialExpression.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/IPartialExpression.java index 5df0157..b258cba 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/IPartialExpression.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/IPartialExpression.java @@ -26,7 +26,11 @@ public interface IPartialExpression { public Expression call(ZenPosition position, IEnvironmentMethod environment, Expression... values); + public ZenType[] predictCallTypes(int numArguments); + public IZenSymbol toSymbol(); + public ZenType getType(); + public ZenType toType(IEnvironmentGlobal environment); } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialJavaClass.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialJavaClass.java index 53c397b..468a727 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialJavaClass.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialJavaClass.java @@ -57,8 +57,18 @@ public class PartialJavaClass implements IPartialExpression { return new SymbolJavaClass(cls); } + @Override + public ZenType getType() { + return null; + } + @Override public ZenType toType(IEnvironmentGlobal environment) { return environment.getType(cls); } + + @Override + public ZenType[] predictCallTypes(int numArguments) { + return new ZenType[numArguments]; + } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialLocal.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialLocal.java index 45b55ae..65d2af0 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialLocal.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialLocal.java @@ -55,11 +55,21 @@ public class PartialLocal implements IPartialExpression { return variable.getType().call(position, environment, eval(environment), values); } + @Override + public ZenType[] predictCallTypes(int numArguments) { + return variable.getType().predictCallTypes(numArguments); + } + @Override public IZenSymbol toSymbol() { return variable; } + @Override + public ZenType getType() { + return variable.getType(); + } + @Override public ZenType toType(IEnvironmentGlobal environment) { environment.error(position, "not a valid type"); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialPackage.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialPackage.java index d812170..93d7141 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialPackage.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialPackage.java @@ -57,11 +57,21 @@ public class PartialPackage implements IPartialExpression { return new ExpressionInvalid(position); } + @Override + public ZenType[] predictCallTypes(int numArguments) { + return new ZenType[numArguments]; + } + @Override public IZenSymbol toSymbol() { return null; // not supposed to be used as symbol } + @Override + public ZenType getType() { + return null; + } + @Override public ZenType toType(IEnvironmentGlobal environment) { environment.error(position, "not a valid type"); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialStaticGenerated.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialStaticGenerated.java index 14f6f05..05fb62f 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialStaticGenerated.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialStaticGenerated.java @@ -6,14 +6,16 @@ package stanhebben.zenscript.expression.partial; +import java.util.Arrays; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; +import stanhebben.zenscript.expression.ExpressionCallStatic; import stanhebben.zenscript.expression.ExpressionInvalid; -import stanhebben.zenscript.expression.ExpressionJavaCallStaticGenerated; import stanhebben.zenscript.symbols.IZenSymbol; import stanhebben.zenscript.symbols.SymbolZenStaticMethod; import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.ZenPosition; /** @@ -67,7 +69,12 @@ public class PartialStaticGenerated implements IPartialExpression { arguments[i] = values[i].cast(position, environment, argumentTypes[i]); } - return new ExpressionJavaCallStaticGenerated(position, owner, method, signature, returnType, arguments); + return new ExpressionCallStatic(position, environment, JavaMethod.getStatic(owner, method, returnType, argumentTypes), arguments); + } + + @Override + public ZenType[] predictCallTypes(int numArguments) { + return Arrays.copyOf(argumentTypes, numArguments); } @Override @@ -75,6 +82,11 @@ public class PartialStaticGenerated implements IPartialExpression { return new SymbolZenStaticMethod(owner, method, signature, argumentTypes, returnType); } + @Override + public ZenType getType() { + return returnType; + } + @Override public ZenType toType(IEnvironmentGlobal environment) { environment.error(position, "not a valid type"); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialStaticGetter.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialStaticGetter.java index ac8e6e2..d517e0f 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialStaticGetter.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialStaticGetter.java @@ -9,11 +9,12 @@ package stanhebben.zenscript.expression.partial; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; +import stanhebben.zenscript.expression.ExpressionCallStatic; import stanhebben.zenscript.expression.ExpressionInvalid; import stanhebben.zenscript.symbols.IZenSymbol; import stanhebben.zenscript.symbols.SymbolJavaStaticGetter; import stanhebben.zenscript.type.ZenType; -import stanhebben.zenscript.type.natives.JavaMethod; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.util.ZenPosition; /** @@ -22,16 +23,16 @@ import stanhebben.zenscript.util.ZenPosition; */ public class PartialStaticGetter implements IPartialExpression { private final ZenPosition position; - private final JavaMethod method; + private final IJavaMethod method; - public PartialStaticGetter(ZenPosition position, JavaMethod method) { + public PartialStaticGetter(ZenPosition position, IJavaMethod method) { this.position = position; this.method = method; } @Override public Expression eval(IEnvironmentGlobal environment) { - return method.callStatic(position, environment); + return new ExpressionCallStatic(position, environment, method); } @Override @@ -51,11 +52,21 @@ public class PartialStaticGetter implements IPartialExpression { return new ExpressionInvalid(position); } + @Override + public ZenType[] predictCallTypes(int numArguments) { + return new ZenType[numArguments]; + } + @Override public IZenSymbol toSymbol() { return new SymbolJavaStaticGetter(method); } + @Override + public ZenType getType() { + return method.getReturnType(); + } + @Override public ZenType toType(IEnvironmentGlobal environment) { environment.error(position, "not a valid type"); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialStaticMethod.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialStaticMethod.java index 4220a99..4892067 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialStaticMethod.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialStaticMethod.java @@ -6,14 +6,16 @@ package stanhebben.zenscript.expression.partial; +import java.util.Arrays; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; +import stanhebben.zenscript.expression.ExpressionCallStatic; import stanhebben.zenscript.expression.ExpressionInvalid; import stanhebben.zenscript.symbols.IZenSymbol; import stanhebben.zenscript.symbols.SymbolJavaStaticMethod; import stanhebben.zenscript.type.ZenType; -import stanhebben.zenscript.type.natives.JavaMethod; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.util.ZenPosition; /** @@ -22,9 +24,9 @@ import stanhebben.zenscript.util.ZenPosition; */ public class PartialStaticMethod implements IPartialExpression { private final ZenPosition position; - private final JavaMethod method; + private final IJavaMethod method; - public PartialStaticMethod(ZenPosition position, JavaMethod method) { + public PartialStaticMethod(ZenPosition position, IJavaMethod method) { this.position = position; this.method = method; } @@ -50,18 +52,28 @@ public class PartialStaticMethod implements IPartialExpression { @Override public Expression call(ZenPosition position, IEnvironmentMethod environment, Expression... values) { if (method.accepts(environment, values)) { - return method.callStatic(position, environment, values); + return new ExpressionCallStatic(position, environment, method, values); } else { environment.error(position, "parameter count mismatch"); return new ExpressionInvalid(position, method.getReturnType()); } } + @Override + public ZenType[] predictCallTypes(int numArguments) { + return Arrays.copyOf(method.getParameterTypes(), numArguments); + } + @Override public IZenSymbol toSymbol() { return new SymbolJavaStaticMethod(method); } + @Override + public ZenType getType() { + return method.getReturnType(); + } + @Override public ZenType toType(IEnvironmentGlobal environment) { return ZenType.ANY; diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialType.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialType.java index b076677..9ee7061 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialType.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/partial/PartialType.java @@ -55,6 +55,16 @@ public class PartialType implements IPartialExpression { public IZenSymbol toSymbol() { return new SymbolType(type); } + + @Override + public ZenType getType() { + return null; // not an expression + } + + @Override + public ZenType[] predictCallTypes(int numArguments) { + return new ZenType[numArguments]; + } @Override public ZenType toType(IEnvironmentGlobal environment) { diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/NFA.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/NFA.java index 2a0017a..e05ad6c 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/NFA.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/NFA.java @@ -65,13 +65,10 @@ public class NFA { Partial[] partials = new Partial[regexp.length]; for (int i = 0; i < regexp.length; i++) { - //System.out.println("Processing regexp " + i + ": " + regexp[i]); partials[i] = processRegExp(new CharStream(regexp[i])); partials[i].head.setFinal(finals[i]); initial.addTransition(partials[i].tailLabel, partials[i].tail); } - - //System.out.println("NFA generated"); } /** diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/TokenStream.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/TokenStream.java index d9ed23f..1984416 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/TokenStream.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/TokenStream.java @@ -230,7 +230,6 @@ public class TokenStream implements Iterator { if (nextChar < 0 && value.length() == 0) { return; // happens on comments at the end of files } - //System.out.println("Value: " + value.length() + " characters: " + value); throw new TokenException(file, line, lineOffset, (char)nextChar); } } catch (IOException ex) { diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpression.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpression.java index a37d330..e457db1 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpression.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpression.java @@ -17,7 +17,6 @@ import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.definitions.ParsedFunctionArgument; import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.ExpressionFloat; -import stanhebben.zenscript.expression.ExpressionFunction; import stanhebben.zenscript.expression.ExpressionInt; import stanhebben.zenscript.expression.ExpressionString; import stanhebben.zenscript.parser.ParseException; @@ -331,7 +330,6 @@ public abstract class ParsedExpression { }*/ case T_ID: return new ParsedExpressionVariable(position, parser.next().getValue()); - // TODO: implement function values case T_FUNCTION: // function (argname, argname, ...) { ...contents... } parser.next(); @@ -360,18 +358,14 @@ public abstract class ParsedExpression { parser.required(T_AOPEN, "{ expected"); - Statement[] statements; - if (parser.optional(T_ACLOSE) != null) { - statements = new Statement[0]; - } else { - ArrayList statementsAL = new ArrayList(); - + List statements = new ArrayList(); + if (parser.optional(T_ACLOSE) == null) { while (parser.optional(T_ACLOSE) == null) { - statementsAL.add(Statement.read(parser, environment)); + statements.add(Statement.read(parser, environment, returnType)); } - statements = statementsAL.toArray(new Statement[statementsAL.size()]); } - return new ParsedExpressionValue(position, new ExpressionFunction(position, arguments, returnType, statements)); + + return new ParsedExpressionFunction(position, returnType, arguments, statements); case T_LT: { Token start = parser.next(); List tokens = new ArrayList(); @@ -380,7 +374,7 @@ public abstract class ParsedExpression { tokens.add(next); next = parser.next(); } - IZenSymbol resolved = parser.getEnvironment().getBracketed(tokens); + IZenSymbol resolved = parser.getEnvironment().getBracketed(environment, tokens); if (resolved == null) { StringBuilder builder = new StringBuilder(); builder.append('<'); @@ -397,7 +391,7 @@ public abstract class ParsedExpression { } else { return new ParsedExpressionValue( start.getPosition(), - parser.getEnvironment().getBracketed(tokens).instance(start.getPosition())); + parser.getEnvironment().getBracketed(environment, tokens).instance(start.getPosition())); } } case T_SQBROPEN: { @@ -431,7 +425,7 @@ public abstract class ParsedExpression { } } - return new ParsedExpressionTable(position, keys, values); + return new ParsedExpressionMap(position, keys, values); } } case T_TRUE: @@ -463,9 +457,9 @@ public abstract class ParsedExpression { return position; } - public abstract IPartialExpression compile(IEnvironmentMethod environment); + public abstract IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType); - public Expression compileKey(IEnvironmentMethod environment) { - return compile(environment).eval(environment); + public Expression compileKey(IEnvironmentMethod environment, ZenType predictedType) { + return compile(environment, predictedType).eval(environment); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionAndAnd.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionAndAnd.java index 128f725..e235946 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionAndAnd.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionAndAnd.java @@ -7,8 +7,9 @@ package stanhebben.zenscript.parser.expression; import stanhebben.zenscript.compiler.IEnvironmentMethod; -import stanhebben.zenscript.expression.ExpressionOrOr; +import stanhebben.zenscript.expression.ExpressionAndAnd; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; /** @@ -27,10 +28,10 @@ public class ParsedExpressionAndAnd extends ParsedExpression { } @Override - public IPartialExpression compile(IEnvironmentMethod environment) { - return new ExpressionOrOr( + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { + return new ExpressionAndAnd( getPosition(), - left.compile(environment).eval(environment), - right.compile(environment).eval(environment)); + left.compile(environment, predictedType).eval(environment), + right.compile(environment, predictedType).eval(environment)); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionArray.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionArray.java index 693cb4c..a60fde6 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionArray.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionArray.java @@ -10,7 +10,12 @@ import java.util.List; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.ExpressionArray; +import stanhebben.zenscript.expression.ExpressionAs; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.ZenTypeArray; +import stanhebben.zenscript.type.ZenTypeArrayBasic; +import stanhebben.zenscript.type.casting.ICastingRule; import stanhebben.zenscript.util.ZenPosition; /** @@ -27,20 +32,52 @@ public class ParsedExpressionArray extends ParsedExpression { } @Override - public IPartialExpression compile(IEnvironmentMethod environment) { + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { + ZenType predictedBaseType = null; + ZenTypeArrayBasic arrayType = ZenType.ANYARRAY; + ICastingRule castingRule = null; + + if (predictedType instanceof ZenTypeArray) { + predictedBaseType = ((ZenTypeArray) predictedType).getBaseType(); + if (predictedType instanceof ZenTypeArrayBasic) { + // TODO: allow any kind of array type + arrayType = (ZenTypeArrayBasic) predictedType; + } + } else { + // find any[] caster that casts to the given type + castingRule = ZenType.ANYARRAY.getCastingRule(predictedType, environment); + if (castingRule != null) { + if (castingRule.getInputType() instanceof ZenTypeArray) { + predictedBaseType = ((ZenTypeArray) castingRule.getInputType()).getBaseType(); + if (castingRule.getInputType() instanceof ZenTypeArrayBasic) { + // TODO: allow any kind of array type + arrayType = (ZenTypeArrayBasic) castingRule.getInputType(); + } + } else { + environment.error(getPosition(), "Invalid caster - any[] caster but input type is not an array"); + castingRule = null; + } + } + } + Expression[] cContents = new Expression[contents.size()]; for (int i = 0; i < contents.size(); i++) { - cContents[i] = contents.get(i).compile(environment).eval(environment); + cContents[i] = contents.get(i).compile(environment, predictedBaseType).eval(environment); + } + Expression result = new ExpressionArray(getPosition(), arrayType, cContents); + if (castingRule != null) { + return new ExpressionAs(getPosition(), result, castingRule); + } else { + return result; } - return new ExpressionArray(getPosition(), cContents); } @Override - public Expression compileKey(IEnvironmentMethod environment) { + public Expression compileKey(IEnvironmentMethod environment, ZenType predictedType) { if (contents.size() == 1 && contents.get(0) instanceof ParsedExpressionVariable) { - return contents.get(0).compile(environment).eval(environment); + return contents.get(0).compile(environment, predictedType).eval(environment); } else { - return compile(environment).eval(environment); + return compile(environment, predictedType).eval(environment); } } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionAssign.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionAssign.java index 6f3b5a4..31e9478 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionAssign.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionAssign.java @@ -8,6 +8,7 @@ package stanhebben.zenscript.parser.expression; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; /** @@ -26,10 +27,10 @@ public class ParsedExpressionAssign extends ParsedExpression { } @Override - public IPartialExpression compile(IEnvironmentMethod environment) { - IPartialExpression cLeft = left.compile(environment); + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { + IPartialExpression cLeft = left.compile(environment, predictedType); return cLeft .assign(getPosition(), environment, - right.compile(environment).eval(environment)); + right.compile(environment, cLeft.getType()).eval(environment)); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionBinary.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionBinary.java index 41c234a..d79dd02 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionBinary.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionBinary.java @@ -10,6 +10,7 @@ import stanhebben.zenscript.annotations.OperatorType; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; /** @@ -30,9 +31,10 @@ public class ParsedExpressionBinary extends ParsedExpression { } @Override - public IPartialExpression compile(IEnvironmentMethod environment) { - Expression cLeft = left.compile(environment).eval(environment); - Expression cRight = right.compile(environment).eval(environment); + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { + // TODO: make better predictions + Expression cLeft = left.compile(environment, predictedType).eval(environment); + Expression cRight = right.compile(environment, predictedType).eval(environment); return cLeft.getType().binary(getPosition(), environment, cLeft, cRight, operator); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionBool.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionBool.java index 1daccc4..3f9d425 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionBool.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionBool.java @@ -9,6 +9,7 @@ package stanhebben.zenscript.parser.expression; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.ExpressionBool; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; /** @@ -25,7 +26,7 @@ public class ParsedExpressionBool extends ParsedExpression { } @Override - public IPartialExpression compile(IEnvironmentMethod environment) { + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { return new ExpressionBool(getPosition(), value); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionCall.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionCall.java index da095be..21bd875 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionCall.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionCall.java @@ -10,6 +10,7 @@ import java.util.List; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; /** @@ -26,13 +27,15 @@ public class ParsedExpressionCall extends ParsedExpression { this.receiver = receiver; this.arguments = arguments; } - + @Override - public IPartialExpression compile(IEnvironmentMethod environment) { - IPartialExpression cReceiver = receiver.compile(environment); + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { + IPartialExpression cReceiver = receiver.compile(environment, null); + ZenType[] predictedTypes = cReceiver.predictCallTypes(arguments.size()); + Expression[] cArguments = new Expression[arguments.size()]; for (int i = 0; i < cArguments.length; i++) { - IPartialExpression cArgument = arguments.get(i).compile(environment); + IPartialExpression cArgument = arguments.get(i).compile(environment, predictedTypes[i]); cArguments[i] = cArgument.eval(environment); } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionCast.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionCast.java index ab42021..b779110 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionCast.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionCast.java @@ -27,9 +27,9 @@ public class ParsedExpressionCast extends ParsedExpression { } @Override - public IPartialExpression compile(IEnvironmentMethod environment) { + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { return value - .compile(environment) + .compile(environment, type) .eval(environment) .cast(getPosition(), environment, type); } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionCompare.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionCompare.java index a91cc9a..6a4ce97 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionCompare.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionCompare.java @@ -10,6 +10,7 @@ import stanhebben.zenscript.annotations.CompareType; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; /** @@ -34,9 +35,9 @@ public class ParsedExpressionCompare extends ParsedExpression { } @Override - public IPartialExpression compile(IEnvironmentMethod environment) { - Expression cLeft = left.compile(environment).eval(environment); - Expression cRight = right.compile(environment).eval(environment); + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { + Expression cLeft = left.compile(environment, null).eval(environment); + Expression cRight = right.compile(environment, null).eval(environment); return cLeft.getType().compare(getPosition(), environment, cLeft, cRight, type); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionConditional.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionConditional.java index 15e19e8..dffb03d 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionConditional.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionConditional.java @@ -9,6 +9,7 @@ package stanhebben.zenscript.parser.expression; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.ExpressionConditional; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; /** @@ -29,11 +30,11 @@ public class ParsedExpressionConditional extends ParsedExpression { } @Override - public IPartialExpression compile(IEnvironmentMethod environment) { + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { return new ExpressionConditional( getPosition(), - condition.compile(environment).eval(environment), - ifThen.compile(environment).eval(environment), - ifElse.compile(environment).eval(environment)); + condition.compile(environment, ZenType.BOOL).eval(environment), + ifThen.compile(environment, predictedType).eval(environment), + ifElse.compile(environment, predictedType).eval(environment)); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionFunction.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionFunction.java new file mode 100644 index 0000000..4183170 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionFunction.java @@ -0,0 +1,83 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.parser.expression; + +import java.lang.reflect.Method; +import java.util.List; +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.definitions.ParsedFunctionArgument; +import stanhebben.zenscript.expression.ExpressionFunction; +import stanhebben.zenscript.expression.ExpressionInvalid; +import stanhebben.zenscript.expression.ExpressionJavaLambda; +import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.statements.Statement; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.ZenTypeAny; +import stanhebben.zenscript.type.ZenTypeNative; +import stanhebben.zenscript.util.ZenPosition; + +/** + * + * @author Stan + */ +public class ParsedExpressionFunction extends ParsedExpression { + private final ZenType returnType; + private final List arguments; + private final List statements; + + public ParsedExpressionFunction(ZenPosition position, ZenType returnType, List arguments, List statements) { + super(position); + + this.returnType = returnType; + this.arguments = arguments; + this.statements = statements; + } + + @Override + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { + if (predictedType != null && predictedType instanceof ZenTypeNative) { + System.out.println("Known predicted function type: " + predictedType); + + ZenTypeNative nativeType = (ZenTypeNative) predictedType; + Class nativeClass = nativeType.getNativeClass(); + if (nativeClass.isInterface() && nativeClass.getMethods().length == 1) { + // functional interface + Method method = nativeClass.getMethods()[0]; + if (returnType != ZenTypeAny.INSTANCE + && !returnType.canCastImplicit(environment.getType(method.getGenericReturnType()), environment)) { + environment.error(getPosition(), "return type not compatible"); + return new ExpressionInvalid(getPosition()); + } + if (arguments.size() != method.getParameterTypes().length) { + environment.error(getPosition(), "number of arguments incorrect"); + return new ExpressionInvalid(getPosition()); + } + for (int i = 0; i < arguments.size(); i++) { + ZenType argumentType = environment.getType(method.getGenericParameterTypes()[i]); + if (arguments.get(i).getType() != ZenTypeAny.INSTANCE + && !argumentType.canCastImplicit(arguments.get(i).getType(), environment)) { + environment.error(getPosition(), "argument " + i + " doesn't match"); + return new ExpressionInvalid(getPosition()); + } + } + + return new ExpressionJavaLambda( + getPosition(), + nativeClass, + arguments, + statements, + environment.getType(nativeClass)); + } else { + environment.error(getPosition(), predictedType.toString() + " is not a functional interface"); + return new ExpressionInvalid(getPosition()); + } + } else { + System.out.println("No known predicted type"); + return new ExpressionFunction(getPosition(), arguments, returnType, statements); + } + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionIndex.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionIndex.java index 4e13f8d..a61463c 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionIndex.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionIndex.java @@ -10,6 +10,7 @@ import stanhebben.zenscript.annotations.OperatorType; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; /** @@ -28,9 +29,10 @@ public class ParsedExpressionIndex extends ParsedExpression { } @Override - public IPartialExpression compile(IEnvironmentMethod environment) { - Expression cValue = value.compile(environment).eval(environment); - Expression cIndex = index.compile(environment).eval(environment); + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { + // TODO: improve type prediction for this + Expression cValue = value.compile(environment, null).eval(environment); + Expression cIndex = index.compile(environment, null).eval(environment); return cValue.getType().binary(getPosition(), environment, cValue, cIndex, OperatorType.INDEXGET); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionIndexSet.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionIndexSet.java index 82cf38a..0a27e99 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionIndexSet.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionIndexSet.java @@ -10,6 +10,7 @@ import stanhebben.zenscript.annotations.OperatorType; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; /** @@ -30,10 +31,11 @@ public class ParsedExpressionIndexSet extends ParsedExpression { } @Override - public IPartialExpression compile(IEnvironmentMethod environment) { - Expression cValue = value.compile(environment).eval(environment); - Expression cIndex = index.compile(environment).eval(environment); - Expression cSetValue = setValue.compile(environment).eval(environment); + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { + // TODO: improve prediction in this expression + Expression cValue = value.compile(environment, null).eval(environment); + Expression cIndex = index.compile(environment, null).eval(environment); + Expression cSetValue = setValue.compile(environment, null).eval(environment); return cValue.getType().trinary(getPosition(), environment, cValue, cIndex, cSetValue,OperatorType.INDEXSET); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionInvalid.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionInvalid.java index c7223d9..941aaf8 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionInvalid.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionInvalid.java @@ -9,6 +9,7 @@ package stanhebben.zenscript.parser.expression; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.ExpressionInvalid; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; /** @@ -21,7 +22,7 @@ public class ParsedExpressionInvalid extends ParsedExpression { } @Override - public IPartialExpression compile(IEnvironmentMethod environment) { - return new ExpressionInvalid(getPosition()); + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { + return new ExpressionInvalid(getPosition(), predictedType == null ? ZenType.ANY : predictedType); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionMap.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionMap.java new file mode 100644 index 0000000..c119e9d --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionMap.java @@ -0,0 +1,79 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.parser.expression; + +import java.util.List; +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.expression.Expression; +import stanhebben.zenscript.expression.ExpressionAs; +import stanhebben.zenscript.expression.ExpressionMap; +import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.ZenTypeAssociative; +import stanhebben.zenscript.type.casting.ICastingRule; +import stanhebben.zenscript.util.ZenPosition; + +/** + * + * @author Stanneke + */ +public class ParsedExpressionMap extends ParsedExpression { + private final List keys; + private final List values; + + public ParsedExpressionMap( + ZenPosition position, + List keys, + List values) { + super(position); + + this.keys = keys; + this.values = values; + } + + @Override + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { + ZenType predictedKeyType = null; + ZenType predictedValueType = null; + ICastingRule castingRule = null; + ZenTypeAssociative mapType = ZenType.ANYMAP; + + if (predictedType instanceof ZenTypeAssociative) { + ZenTypeAssociative inputType = (ZenTypeAssociative) predictedType; + predictedKeyType = inputType.getKeyType(); + predictedValueType = inputType.getValueType(); + mapType = inputType; + } else { + castingRule = ZenType.ANYMAP.getCastingRule(predictedType, environment); + if (castingRule != null) { + if (castingRule.getInputType() instanceof ZenTypeAssociative) { + ZenTypeAssociative inputType = (ZenTypeAssociative) castingRule.getInputType(); + predictedKeyType = inputType.getKeyType(); + predictedValueType = inputType.getValueType(); + mapType = inputType; + } else { + environment.error(getPosition(), "Caster found for any[any] but its input is not an associative array"); + } + } + } + + Expression[] cKeys = new Expression[keys.size()]; + Expression[] cValues = new Expression[values.size()]; + + for (int i = 0; i < keys.size(); i++) { + cKeys[i] = keys.get(i).compileKey(environment, predictedKeyType); + cValues[i] = values.get(i).compile(environment, predictedValueType).eval(environment); + } + + Expression result = new ExpressionMap(getPosition(), cKeys, cValues, mapType); + if (castingRule != null) { + return new ExpressionAs(getPosition(), result, castingRule); + } else { + return result; + } + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionMember.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionMember.java index 18c4c59..2924128 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionMember.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionMember.java @@ -8,6 +8,7 @@ package stanhebben.zenscript.parser.expression; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; /** @@ -26,7 +27,7 @@ public class ParsedExpressionMember extends ParsedExpression { } @Override - public IPartialExpression compile(IEnvironmentMethod environment) { - return value.compile(environment).getMember(getPosition(), environment, member); + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { + return value.compile(environment, null).getMember(getPosition(), environment, member); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionNull.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionNull.java index 7f1d8c6..fc0c01f 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionNull.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionNull.java @@ -9,6 +9,7 @@ package stanhebben.zenscript.parser.expression; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.ExpressionNull; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; /** @@ -21,7 +22,7 @@ public class ParsedExpressionNull extends ParsedExpression { } @Override - public IPartialExpression compile(IEnvironmentMethod environment) { + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { return new ExpressionNull(getPosition()); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionOpAssign.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionOpAssign.java index 026daf9..49b2ae0 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionOpAssign.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionOpAssign.java @@ -10,6 +10,7 @@ import stanhebben.zenscript.annotations.OperatorType; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; /** @@ -30,12 +31,13 @@ public class ParsedExpressionOpAssign extends ParsedExpression { } @Override - public IPartialExpression compile(IEnvironmentMethod environment) { - Expression cLeft = left.compile(environment).eval(environment); - Expression cRight = right.compile(environment).eval(environment); + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { + // TODO: validate if the prediction rules are sound + Expression cLeft = left.compile(environment, predictedType).eval(environment); + Expression cRight = right.compile(environment, cLeft.getType()).eval(environment); Expression value = cLeft.getType().binary(getPosition(), environment, cLeft, cRight, operator); - return left.compile(environment).assign(getPosition(), environment, value); + return left.compile(environment, predictedType).assign(getPosition(), environment, value); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionOrOr.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionOrOr.java index 6f667ce..3a49767 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionOrOr.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionOrOr.java @@ -7,8 +7,10 @@ package stanhebben.zenscript.parser.expression; import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.ExpressionOrOr; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; /** @@ -27,10 +29,23 @@ public class ParsedExpressionOrOr extends ParsedExpression { } @Override - public IPartialExpression compile(IEnvironmentMethod environment) { + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { + Expression cLeft = left.compile(environment, predictedType).eval(environment); + Expression cRight = right.compile(environment, predictedType).eval(environment); + + ZenType type; + if (cRight.getType().canCastImplicit(cLeft.getType(), environment)) { + type = cLeft.getType(); + } else if (cLeft.getType().canCastImplicit(cRight.getType(), environment)) { + type = cRight.getType(); + } else { + environment.error(getPosition(), "These types could not be unified: " + cLeft.getType() + " and " + cRight.getType()); + type = ZenType.ANY; + } + return new ExpressionOrOr( getPosition(), - left.compile(environment).eval(environment), - right.compile(environment).eval(environment)); + cLeft.cast(getPosition(), environment, type), + cRight.cast(getPosition(), environment, type)); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionTable.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionTable.java deleted file mode 100644 index 0d0f683..0000000 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionTable.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -package stanhebben.zenscript.parser.expression; - -import java.util.List; -import stanhebben.zenscript.compiler.IEnvironmentMethod; -import stanhebben.zenscript.expression.Expression; -import stanhebben.zenscript.expression.ExpressionTable; -import stanhebben.zenscript.expression.partial.IPartialExpression; -import stanhebben.zenscript.util.ZenPosition; - -/** - * - * @author Stanneke - */ -public class ParsedExpressionTable extends ParsedExpression { - private final List keys; - private final List values; - - public ParsedExpressionTable( - ZenPosition position, - List keys, - List values) { - super(position); - - this.keys = keys; - this.values = values; - } - - @Override - public IPartialExpression compile(IEnvironmentMethod environment) { - Expression[] cKeys = new Expression[keys.size()]; - Expression[] cValues = new Expression[values.size()]; - - for (int i = 0; i < keys.size(); i++) { - cKeys[i] = keys.get(i).compileKey(environment); - cValues[i] = values.get(i).compile(environment).eval(environment); - } - - return new ExpressionTable(getPosition(), cKeys, cValues); - } -} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionUnary.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionUnary.java index 83bafc8..2aa4448 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionUnary.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionUnary.java @@ -10,6 +10,7 @@ import stanhebben.zenscript.annotations.OperatorType; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; /** @@ -28,8 +29,9 @@ public class ParsedExpressionUnary extends ParsedExpression { } @Override - public IPartialExpression compile(IEnvironmentMethod environment) { - Expression cValue = value.compile(environment).eval(environment); + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { + // TODO: improve type predictions? + Expression cValue = value.compile(environment, predictedType).eval(environment); return cValue.getType().unary(getPosition(), environment, cValue, operator); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionValue.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionValue.java index 9cfd9bd..6ac458c 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionValue.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionValue.java @@ -8,6 +8,7 @@ package stanhebben.zenscript.parser.expression; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; /** @@ -26,7 +27,7 @@ public class ParsedExpressionValue extends ParsedExpression { } @Override - public IPartialExpression compile(IEnvironmentMethod environment) { + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { return value; } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionVariable.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionVariable.java index 1b7dfdd..f1cb797 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionVariable.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpressionVariable.java @@ -11,6 +11,7 @@ import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.ExpressionInvalid; import stanhebben.zenscript.expression.ExpressionString; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; /** @@ -27,18 +28,24 @@ public class ParsedExpressionVariable extends ParsedExpression { } @Override - public IPartialExpression compile(IEnvironmentMethod environment) { + public IPartialExpression compile(IEnvironmentMethod environment, ZenType predictedType) { IPartialExpression result = environment.getValue(name, getPosition()); if (result == null) { - environment.error(getPosition(), "could not find " + name); - return new ExpressionInvalid(getPosition()); + // enable usage of static members of the same type as the predicted type (eg. enum values) + IPartialExpression member = predictedType.getStaticMember(getPosition(), environment, name); + if (member == null || member.getType().getCastingRule(predictedType, environment) == null) { + environment.error(getPosition(), "could not find " + name); + return new ExpressionInvalid(getPosition()); + } else { + return member; + } } else { return result; } } @Override - public Expression compileKey(IEnvironmentMethod environment) { + public Expression compileKey(IEnvironmentMethod environment, ZenType predictedType) { return new ExpressionString(getPosition(), name); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/statements/Statement.java b/ZenScript/src/main/java/stanhebben/zenscript/statements/Statement.java index 014b616..c1415e4 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/statements/Statement.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/statements/Statement.java @@ -13,14 +13,14 @@ import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; public abstract class Statement { - public static Statement read(ZenTokener parser, IEnvironmentGlobal environment) { + public static Statement read(ZenTokener parser, IEnvironmentGlobal environment, ZenType returnType) { Token next = parser.peek(); switch (next.getType()) { case T_AOPEN: { Token t = parser.next(); ArrayList statements = new ArrayList(); while (parser.optional(T_ACLOSE) == null) { - statements.add(read(parser, environment)); + statements.add(read(parser, environment, returnType)); } return new StatementBlock(t.getPosition(), statements); } @@ -28,7 +28,7 @@ public abstract class Statement { parser.next(); ParsedExpression expression = ParsedExpression.read(parser, environment); parser.required(T_SEMICOLON, "; expected"); - return new StatementReturn(next.getPosition(), expression); + return new StatementReturn(next.getPosition(), returnType, expression); } case T_VAR: case T_VAL: { @@ -49,10 +49,10 @@ public abstract class Statement { case T_IF: { Token t = parser.next(); ParsedExpression expression = ParsedExpression.read(parser, environment); - Statement onIf = read(parser, environment); + Statement onIf = read(parser, environment, returnType); Statement onElse = null; if (parser.optional(T_ELSE) != null) { - onElse = read(parser, environment); + onElse = read(parser, environment, returnType); } return new StatementIf(t.getPosition(), expression, onIf, onElse); } @@ -68,7 +68,7 @@ public abstract class Statement { parser.required(T_IN, "in expected"); ParsedExpression source = ParsedExpression.read(parser, environment); - Statement content = read(parser, environment); + Statement content = read(parser, environment, null); return new StatementForeach( t.getPosition(), names.toArray(new String[names.size()]), diff --git a/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementExpression.java b/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementExpression.java index e678f66..4ab8bee 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementExpression.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementExpression.java @@ -16,7 +16,7 @@ public class StatementExpression extends Statement { @Override public void compile(IEnvironmentMethod environment) { environment.getOutput().position(getPosition()); - expression.compile(environment) + expression.compile(environment, null) .eval(environment) .compile(false, environment); } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementForeach.java b/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementForeach.java index c8fa7d6..d97e5ae 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementForeach.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementForeach.java @@ -26,7 +26,7 @@ public class StatementForeach extends Statement { @Override public void compile(IEnvironmentMethod environment) { - Expression cList = list.compile(environment).eval(environment); + Expression cList = list.compile(environment, ZenType.ANYARRAY).eval(environment); ZenType listType = cList.getType(); IZenIterator iterator = listType.makeIterator(varnames.length, environment); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementIf.java b/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementIf.java index 1fe1705..787106a 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementIf.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementIf.java @@ -5,7 +5,6 @@ import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.parser.expression.ParsedExpression; import stanhebben.zenscript.type.ZenType; -import stanhebben.zenscript.type.ZenTypeBool; import stanhebben.zenscript.util.MethodOutput; import stanhebben.zenscript.util.ZenPosition; @@ -26,7 +25,7 @@ public class StatementIf extends Statement { public void compile(IEnvironmentMethod environment) { environment.getOutput().position(getPosition()); - Expression cCondition = condition.compile(environment).eval(environment); + Expression cCondition = condition.compile(environment, ZenType.BOOL).eval(environment); ZenType expressionType = cCondition.getType(); if (expressionType.canCastImplicit(ZenType.BOOL, environment)) { Label labelEnd = new Label(); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementReturn.java b/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementReturn.java index f2c7022..a56aacb 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementReturn.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementReturn.java @@ -4,14 +4,17 @@ import org.objectweb.asm.Type; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.parser.expression.ParsedExpression; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.ZenPosition; public class StatementReturn extends Statement { + private final ZenType returnType; private final ParsedExpression expression; - public StatementReturn(ZenPosition position, ParsedExpression expression) { + public StatementReturn(ZenPosition position, ZenType returnType, ParsedExpression expression) { super(position); + this.returnType = returnType; this.expression = expression; } @@ -31,7 +34,7 @@ public class StatementReturn extends Statement { if (expression == null) { environment.getOutput().ret(); } else { - Expression cExpression = expression.compile(environment).eval(environment); + Expression cExpression = expression.compile(environment, returnType).eval(environment); cExpression.compile(true, environment); Type returnType = cExpression.getType().toASMType(); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementVar.java b/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementVar.java index 61f1dab..784ced4 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementVar.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementVar.java @@ -39,7 +39,7 @@ public class StatementVar extends Statement { Expression cInitializer = initializer == null ? null - : initializer.compile(environment).eval(environment); + : initializer.compile(environment, type).eval(environment); ZenType cType = type == null ? (cInitializer == null ? ZenTypeAny.INSTANCE : cInitializer.getType()) : type; SymbolLocal symbol = new SymbolLocal(cType, isFinal); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/symbols/SymbolJavaStaticGetter.java b/ZenScript/src/main/java/stanhebben/zenscript/symbols/SymbolJavaStaticGetter.java index a16df7f..e213f55 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/symbols/SymbolJavaStaticGetter.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/symbols/SymbolJavaStaticGetter.java @@ -8,7 +8,7 @@ package stanhebben.zenscript.symbols; import stanhebben.zenscript.expression.partial.IPartialExpression; import stanhebben.zenscript.expression.partial.PartialStaticGetter; -import stanhebben.zenscript.type.natives.JavaMethod; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.util.ZenPosition; /** @@ -16,9 +16,9 @@ import stanhebben.zenscript.util.ZenPosition; * @author Stanneke */ public class SymbolJavaStaticGetter implements IZenSymbol { - private final JavaMethod method; + private final IJavaMethod method; - public SymbolJavaStaticGetter(JavaMethod method) { + public SymbolJavaStaticGetter(IJavaMethod method) { this.method = method; } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/symbols/SymbolJavaStaticMethod.java b/ZenScript/src/main/java/stanhebben/zenscript/symbols/SymbolJavaStaticMethod.java index d45a656..7e9285d 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/symbols/SymbolJavaStaticMethod.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/symbols/SymbolJavaStaticMethod.java @@ -8,7 +8,7 @@ package stanhebben.zenscript.symbols; import stanhebben.zenscript.expression.partial.IPartialExpression; import stanhebben.zenscript.expression.partial.PartialStaticMethod; -import stanhebben.zenscript.type.natives.JavaMethod; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.util.ZenPosition; /** @@ -16,9 +16,9 @@ import stanhebben.zenscript.util.ZenPosition; * @author Stanneke */ public class SymbolJavaStaticMethod implements IZenSymbol { - private final JavaMethod method; + private final IJavaMethod method; - public SymbolJavaStaticMethod(JavaMethod method) { + public SymbolJavaStaticMethod(IJavaMethod method) { this.method = method; } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenType.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenType.java index 5889044..9b1c579 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenType.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenType.java @@ -1,6 +1,8 @@ package stanhebben.zenscript.type; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import org.objectweb.asm.Type; import stanhebben.zenscript.TypeExpansion; import stanhebben.zenscript.ZenTokener; @@ -12,22 +14,38 @@ import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.parser.ParseException; import stanhebben.zenscript.parser.Token; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.casting.CastingRuleDelegateMap; +import stanhebben.zenscript.type.casting.ICastingRule; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; import stanhebben.zenscript.type.expand.ZenExpandCaster; +import stanhebben.zenscript.type.natives.IJavaMethod; +import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.ZenPosition; +import static stanhebben.zenscript.util.ZenTypeUtil.EMPTY_REGISTRY; public abstract class ZenType { public static final ZenTypeAny ANY = ZenTypeAny.INSTANCE; public static final ZenTypeBool BOOL = new ZenTypeBool(); + public static final ZenTypeBoolObject BOOLOBJECT = ZenTypeBoolObject.INSTANCE; public static final ZenTypeByte BYTE = ZenTypeByte.INSTANCE; + public static final ZenTypeByteObject BYTEOBJECT = ZenTypeByteObject.INSTANCE; public static final ZenTypeShort SHORT = ZenTypeShort.INSTANCE; + public static final ZenTypeShortObject SHORTOBJECT = ZenTypeShortObject.INSTANCE; public static final ZenTypeInt INT = ZenTypeInt.INSTANCE; + public static final ZenTypeIntObject INTOBJECT = ZenTypeIntObject.INSTANCE; public static final ZenTypeLong LONG = ZenTypeLong.INSTANCE; + public static final ZenTypeLongObject LONGOBJECT = ZenTypeLongObject.INSTANCE; public static final ZenTypeFloat FLOAT = ZenTypeFloat.INSTANCE; + public static final ZenTypeFloatObject FLOATOBJECT = ZenTypeFloatObject.INSTANCE; public static final ZenTypeDouble DOUBLE = ZenTypeDouble.INSTANCE; + public static final ZenTypeDoubleObject DOUBLEOBJECT = ZenTypeDoubleObject.INSTANCE; public static final ZenTypeString STRING = ZenTypeString.INSTANCE; public static final ZenTypeVoid VOID = ZenTypeVoid.INSTANCE; public static final ZenTypeNull NULL = ZenTypeNull.INSTANCE; + public static final ZenTypeArrayBasic ANYARRAY = new ZenTypeArrayBasic(ANY); + public static final ZenTypeAssociative ANYMAP = new ZenTypeAssociative(ANY, ANY); + public static final int NUM_BYTE = 1; public static final int NUM_SHORT = 2; public static final int NUM_INT = 3; @@ -35,6 +53,54 @@ public abstract class ZenType { public static final int NUM_FLOAT = 5; public static final int NUM_DOUBLE = 6; + protected static final IJavaMethod BOOL_VALUEOF = JavaMethod.get(EMPTY_REGISTRY, Boolean.class, "valueOf", boolean.class); + protected static final IJavaMethod BYTE_VALUEOF = JavaMethod.get(EMPTY_REGISTRY, Byte.class, "valueOf", byte.class); + protected static final IJavaMethod SHORT_VALUEOF = JavaMethod.get(EMPTY_REGISTRY, Short.class, "valueOf", short.class); + protected static final IJavaMethod INT_VALUEOF = JavaMethod.get(EMPTY_REGISTRY, Integer.class, "valueOf", int.class); + protected static final IJavaMethod LONG_VALUEOF = JavaMethod.get(EMPTY_REGISTRY, Long.class, "valueOf", long.class); + protected static final IJavaMethod FLOAT_VALUEOF = JavaMethod.get(EMPTY_REGISTRY, Float.class, "valueOf", float.class); + protected static final IJavaMethod DOUBLE_VALUEOF = JavaMethod.get(EMPTY_REGISTRY, Double.class, "valueOf", double.class); + + protected static final IJavaMethod BOOL_VALUE = JavaMethod.get(EMPTY_REGISTRY, Boolean.class, "booleanValue"); + protected static final IJavaMethod BYTE_VALUE = JavaMethod.get(EMPTY_REGISTRY, Number.class, "byteValue"); + protected static final IJavaMethod SHORT_VALUE = JavaMethod.get(EMPTY_REGISTRY, Number.class, "shortValue"); + protected static final IJavaMethod INT_VALUE = JavaMethod.get(EMPTY_REGISTRY, Number.class, "intValue"); + protected static final IJavaMethod LONG_VALUE = JavaMethod.get(EMPTY_REGISTRY, Number.class, "longValue"); + protected static final IJavaMethod FLOAT_VALUE = JavaMethod.get(EMPTY_REGISTRY, Number.class, "floatValue"); + protected static final IJavaMethod DOUBLE_VALUE = JavaMethod.get(EMPTY_REGISTRY, Number.class, "doubleValue"); + + protected static final IJavaMethod BOOL_TOSTRING_STATIC = JavaMethod.get(EMPTY_REGISTRY, Boolean.class, "toString", boolean.class); + protected static final IJavaMethod BYTE_TOSTRING_STATIC = JavaMethod.get(EMPTY_REGISTRY, Byte.class, "toString", byte.class); + protected static final IJavaMethod SHORT_TOSTRING_STATIC = JavaMethod.get(EMPTY_REGISTRY, Short.class, "toString", short.class); + protected static final IJavaMethod INT_TOSTRING_STATIC = JavaMethod.get(EMPTY_REGISTRY, Integer.class, "toString", int.class); + protected static final IJavaMethod LONG_TOSTRING_STATIC = JavaMethod.get(EMPTY_REGISTRY, Long.class, "toString", long.class); + protected static final IJavaMethod FLOAT_TOSTRING_STATIC = JavaMethod.get(EMPTY_REGISTRY, Float.class, "toString", float.class); + protected static final IJavaMethod DOUBLE_TOSTRING_STATIC = JavaMethod.get(EMPTY_REGISTRY, Double.class, "toString", double.class); + + protected static final IJavaMethod BOOL_TOSTRING = JavaMethod.get(EMPTY_REGISTRY, Boolean.class, "toString"); + protected static final IJavaMethod BYTE_TOSTRING = JavaMethod.get(EMPTY_REGISTRY, Byte.class, "toString"); + protected static final IJavaMethod SHORT_TOSTRING = JavaMethod.get(EMPTY_REGISTRY, Short.class, "toString"); + protected static final IJavaMethod INT_TOSTRING = JavaMethod.get(EMPTY_REGISTRY, Integer.class, "toString"); + protected static final IJavaMethod LONG_TOSTRING = JavaMethod.get(EMPTY_REGISTRY, Long.class, "toString"); + protected static final IJavaMethod FLOAT_TOSTRING = JavaMethod.get(EMPTY_REGISTRY, Float.class, "toString"); + protected static final IJavaMethod DOUBLE_TOSTRING = JavaMethod.get(EMPTY_REGISTRY, Double.class, "toString"); + + protected static final IJavaMethod PARSE_BOOL = JavaMethod.get(EMPTY_REGISTRY, Boolean.class, "parseBoolean", String.class); + protected static final IJavaMethod PARSE_BYTE = JavaMethod.get(EMPTY_REGISTRY, Byte.class, "parseByte", String.class); + protected static final IJavaMethod PARSE_SHORT = JavaMethod.get(EMPTY_REGISTRY, Short.class, "parseShort", String.class); + protected static final IJavaMethod PARSE_INT = JavaMethod.get(EMPTY_REGISTRY, Integer.class, "parseInt", String.class); + protected static final IJavaMethod PARSE_LONG = JavaMethod.get(EMPTY_REGISTRY, Long.class, "parseLong", String.class); + protected static final IJavaMethod PARSE_FLOAT = JavaMethod.get(EMPTY_REGISTRY, Float.class, "parseFloat", String.class); + protected static final IJavaMethod PARSE_DOUBLE = JavaMethod.get(EMPTY_REGISTRY, Double.class, "parseDouble", String.class); + + protected static final IJavaMethod PARSE_BOOL_OBJECT = JavaMethod.get(EMPTY_REGISTRY, Boolean.class, "valueOf", String.class); + protected static final IJavaMethod PARSE_BYTE_OBJECT = JavaMethod.get(EMPTY_REGISTRY, Byte.class, "valueOf", String.class); + protected static final IJavaMethod PARSE_SHORT_OBJECT = JavaMethod.get(EMPTY_REGISTRY, Short.class, "valueOf", String.class); + protected static final IJavaMethod PARSE_INT_OBJECT = JavaMethod.get(EMPTY_REGISTRY, Integer.class, "valueOf", String.class); + protected static final IJavaMethod PARSE_LONG_OBJECT = JavaMethod.get(EMPTY_REGISTRY, Long.class, "valueOf", String.class); + protected static final IJavaMethod PARSE_FLOAT_OBJECT = JavaMethod.get(EMPTY_REGISTRY, Float.class, "valueOf", String.class); + protected static final IJavaMethod PARSE_DOUBLE_OBJECT = JavaMethod.get(EMPTY_REGISTRY, Double.class, "valueOf", String.class); + public static ZenType parse(String type, IEnvironmentGlobal environment) { try { ZenTokener parser = new ZenTokener(type, environment.getEnvironment()); @@ -99,7 +165,6 @@ public abstract class ZenType { } if (partial != null) { base = partial.toType(environment); - System.out.println("Parsed type " + base.getName()); } break; default: @@ -118,6 +183,8 @@ public abstract class ZenType { return base; } + private Map castingRules = null; + public abstract Expression unary( ZenPosition position, IEnvironmentGlobal environment, @@ -163,15 +230,35 @@ public abstract class ZenType { Expression receiver, Expression... arguments); - public abstract Expression cast(ZenPosition position, IEnvironmentGlobal environment, Expression value, ZenType type); + public ZenType[] predictCallTypes(int numArguments) { + return new ZenType[numArguments]; + } + + public abstract void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters); public abstract IZenIterator makeIterator( int numValues, IEnvironmentMethod methodOutput); - public abstract boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment); + public ICastingRule getCastingRule(ZenType type, IEnvironmentGlobal environment) { + if (castingRules == null) { + castingRules = new HashMap(); + constructCastingRules(environment, new CastingRuleDelegateMap(castingRules), true); + } + + return castingRules.get(type); + } + + public final boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { + if (equals(type)) + return true; + + return getCastingRule(type, environment) != null; + } - public abstract boolean canCastExplicit(ZenType type, IEnvironmentGlobal environment); + public boolean canCastExplicit(ZenType type, IEnvironmentGlobal environment) { + return canCastImplicit(type, environment); + } public abstract Class toJavaClass(); @@ -183,7 +270,17 @@ public abstract class ZenType { public abstract boolean isPointer(); - public abstract void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type); + public final void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { + if (equals(type)) + return; + + ICastingRule castingRule = getCastingRule(type, environment); + if (castingRule != null) { + castingRule.compile(environment); + } else { + throw new RuntimeException("Cannot cast " + getName() + " to " + type.getName()); + } + } public abstract String getAnyClassName(IEnvironmentGlobal environment); @@ -251,6 +348,13 @@ public abstract class ZenType { return null; } + protected void constructExpansionCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules) { + TypeExpansion expansion = environment.getExpansion(getName()); + if (expansion != null) { + expansion.constructCastingRules(environment, rules); + } + } + protected Expression castExpansion( ZenPosition position, IEnvironmentGlobal environment, diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeAny.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeAny.java index b4b70fc..0a15feb 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeAny.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeAny.java @@ -1,24 +1,30 @@ package stanhebben.zenscript.type; -import java.util.HashMap; -import java.util.Map; -import org.objectweb.asm.Label; import org.objectweb.asm.Type; import stanhebben.zenscript.annotations.CompareType; import stanhebben.zenscript.annotations.OperatorType; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; -import stanhebben.zenscript.expression.ExpressionAs; import stanhebben.zenscript.expression.ExpressionCompareGeneric; import stanhebben.zenscript.expression.ExpressionInvalid; -import stanhebben.zenscript.expression.ExpressionJavaCallVirtual; +import stanhebben.zenscript.expression.ExpressionCallVirtual; import stanhebben.zenscript.expression.ExpressionNull; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.casting.CastingAnyBool; +import stanhebben.zenscript.type.casting.CastingAnyByte; +import stanhebben.zenscript.type.casting.CastingAnyDouble; +import stanhebben.zenscript.type.casting.CastingAnyFloat; +import stanhebben.zenscript.type.casting.CastingAnyInt; +import stanhebben.zenscript.type.casting.CastingAnyLong; +import stanhebben.zenscript.type.casting.CastingAnyShort; +import stanhebben.zenscript.type.casting.CastingAnyString; +import stanhebben.zenscript.type.casting.CastingRuleAnyAs; +import stanhebben.zenscript.type.casting.CastingRuleNullableStaticMethod; +import stanhebben.zenscript.type.casting.ICastingRule; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; import stanhebben.zenscript.type.natives.JavaMethod; import static stanhebben.zenscript.util.AnyClassWriter.*; -import stanhebben.zenscript.util.MethodCompiler; -import stanhebben.zenscript.util.MethodOutput; import stanhebben.zenscript.util.ZenPosition; import static stanhebben.zenscript.util.ZenTypeUtil.signature; import stanhebben.zenscript.value.IAny; @@ -30,205 +36,6 @@ import stanhebben.zenscript.value.IAny; public class ZenTypeAny extends ZenType { public static final ZenTypeAny INSTANCE = new ZenTypeAny(); - private static final Map CASTERS; - - static { - CASTERS = new HashMap(); - CASTERS.put("bool", new MethodCompiler() { - @Override - public void compile(MethodOutput output) { - output.invokeInterface(IAny.class, "asBool", boolean.class); - } - }); - CASTERS.put("byte", new MethodCompiler() { - @Override - public void compile(MethodOutput output) { - output.invokeInterface(IAny.class, "asByte", byte.class); - } - }); - CASTERS.put("short", new MethodCompiler() { - @Override - public void compile(MethodOutput output) { - output.invokeInterface(IAny.class, "asShort", short.class); - } - }); - CASTERS.put("int", new MethodCompiler() { - @Override - public void compile(MethodOutput output) { - output.invokeInterface(IAny.class, "asInt", int.class); - } - }); - CASTERS.put("long", new MethodCompiler() { - @Override - public void compile(MethodOutput output) { - output.invokeInterface(IAny.class, "asLong", long.class); - } - }); - CASTERS.put("float", new MethodCompiler() { - @Override - public void compile(MethodOutput output) { - output.invokeInterface(IAny.class, "asFloat", float.class); - } - }); - CASTERS.put("double", new MethodCompiler() { - @Override - public void compile(MethodOutput output) { - output.invokeInterface(IAny.class, "asDouble", double.class); - } - }); - CASTERS.put("string", new MethodCompiler() { - @Override - public void compile(MethodOutput output) { - Label lblNull = new Label(); - Label lblAfter = new Label(); - output.dup(); - output.ifNull(lblNull); - output.invokeInterface(IAny.class, "asString", String.class); - output.goTo(lblAfter); - - output.label(lblNull); - output.pop(); - output.aConstNull(); - output.label(lblAfter); - } - }); - CASTERS.put(Boolean.class.getName(), new MethodCompiler() { - @Override - public void compile(MethodOutput output) { - Label lblNull = new Label(); - Label lblAfter = new Label(); - output.dup(); - output.ifNull(lblNull); - output.invokeInterface(IAny.class, "asBool", boolean.class); - output.invokeStatic(Boolean.class, "valueOf", Boolean.class, boolean.class); - output.goTo(lblAfter); - - output.label(lblNull); - output.pop(); - output.aConstNull(); - output.label(lblAfter); - } - }); - CASTERS.put(Byte.class.getName(), new MethodCompiler() { - @Override - public void compile(MethodOutput output) { - Label lblNull = new Label(); - Label lblAfter = new Label(); - output.dup(); - output.ifNull(lblNull); - output.invokeInterface(IAny.class, "asByte", boolean.class); - output.invokeStatic(Byte.class, "valueOf", Byte.class, byte.class); - output.goTo(lblAfter); - - output.label(lblNull); - output.pop(); - output.aConstNull(); - output.label(lblAfter); - } - }); - CASTERS.put(Short.class.getName(), new MethodCompiler() { - @Override - public void compile(MethodOutput output) { - Label lblNull = new Label(); - Label lblAfter = new Label(); - output.dup(); - output.ifNull(lblNull); - output.invokeInterface(IAny.class, "asShort", short.class); - output.invokeStatic(Short.class, "valueOf", Short.class, short.class); - output.goTo(lblAfter); - - output.label(lblNull); - output.pop(); - output.aConstNull(); - output.label(lblAfter); - } - }); - CASTERS.put(Integer.class.getName(), new MethodCompiler() { - @Override - public void compile(MethodOutput output) { - Label lblNull = new Label(); - Label lblAfter = new Label(); - output.dup(); - output.ifNull(lblNull); - output.invokeInterface(IAny.class, "asInt", int.class); - output.invokeStatic(Integer.class, "valueOf", Integer.class, int.class); - output.goTo(lblAfter); - - output.label(lblNull); - output.pop(); - output.aConstNull(); - output.label(lblAfter); - } - }); - CASTERS.put(Long.class.getName(), new MethodCompiler() { - @Override - public void compile(MethodOutput output) { - Label lblNull = new Label(); - Label lblAfter = new Label(); - output.dup(); - output.ifNull(lblNull); - output.invokeInterface(IAny.class, "asLong", long.class); - output.invokeStatic(Long.class, "valueOf", Long.class, long.class); - output.goTo(lblAfter); - - output.label(lblNull); - output.pop(); - output.aConstNull(); - output.label(lblAfter); - } - }); - CASTERS.put(Float.class.getName(), new MethodCompiler() { - @Override - public void compile(MethodOutput output) { - Label lblNull = new Label(); - Label lblAfter = new Label(); - output.dup(); - output.ifNull(lblNull); - output.invokeInterface(IAny.class, "asFloat", float.class); - output.invokeStatic(Float.class, "valueOf", Float.class, float.class); - output.goTo(lblAfter); - - output.label(lblNull); - output.pop(); - output.aConstNull(); - output.label(lblAfter); - } - }); - CASTERS.put(Double.class.getName(), new MethodCompiler() { - @Override - public void compile(MethodOutput output) { - Label lblNull = new Label(); - Label lblAfter = new Label(); - output.dup(); - output.ifNull(lblNull); - output.invokeInterface(IAny.class, "asDouble", double.class); - output.invokeStatic(Double.class, "valueOf", Double.class, double.class); - output.goTo(lblAfter); - - output.label(lblNull); - output.pop(); - output.aConstNull(); - output.label(lblAfter); - } - }); - CASTERS.put(String.class.getName(), new MethodCompiler() { - @Override - public void compile(MethodOutput output) { - Label lblNull = new Label(); - Label lblAfter = new Label(); - output.dup(); - output.ifNull(lblNull); - output.invokeInterface(IAny.class, "asString", String.class); - output.goTo(lblAfter); - - output.label(lblNull); - output.pop(); - output.aConstNull(); - output.label(lblAfter); - } - }); - } - private ZenTypeAny() {} @Override @@ -247,12 +54,40 @@ public class ZenTypeAny extends ZenType { public IZenIterator makeIterator(int numValues, IEnvironmentMethod methodOutput) { return null; // TODO: handle iteration on any-values } - + @Override - public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { - return true; + public ICastingRule getCastingRule(ZenType type, IEnvironmentGlobal environment) { + ICastingRule base = super.getCastingRule(type, environment); + if (base == null) { + return new CastingRuleAnyAs(type); + } else { + return base; + } } - + + @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + rules.registerCastingRule(BOOL, CastingAnyBool.INSTANCE); + rules.registerCastingRule(BOOLOBJECT, new CastingRuleNullableStaticMethod(BOOL_VALUEOF, CastingAnyBool.INSTANCE)); + rules.registerCastingRule(BYTE, CastingAnyByte.INSTANCE); + rules.registerCastingRule(BYTEOBJECT, new CastingRuleNullableStaticMethod(BYTE_VALUEOF, CastingAnyByte.INSTANCE)); + rules.registerCastingRule(SHORT, CastingAnyShort.INSTANCE); + rules.registerCastingRule(SHORTOBJECT, new CastingRuleNullableStaticMethod(SHORT_VALUEOF, CastingAnyShort.INSTANCE)); + rules.registerCastingRule(INT, CastingAnyInt.INSTANCE); + rules.registerCastingRule(INTOBJECT, new CastingRuleNullableStaticMethod(INT_VALUEOF, CastingAnyInt.INSTANCE)); + rules.registerCastingRule(LONG, CastingAnyLong.INSTANCE); + rules.registerCastingRule(LONGOBJECT, new CastingRuleNullableStaticMethod(LONG_VALUEOF, CastingAnyLong.INSTANCE)); + rules.registerCastingRule(FLOAT, CastingAnyFloat.INSTANCE); + rules.registerCastingRule(FLOATOBJECT, new CastingRuleNullableStaticMethod(FLOAT_VALUEOF, CastingAnyFloat.INSTANCE)); + rules.registerCastingRule(DOUBLE, CastingAnyDouble.INSTANCE); + rules.registerCastingRule(DOUBLEOBJECT, new CastingRuleNullableStaticMethod(DOUBLE_VALUEOF, CastingAnyDouble.INSTANCE)); + rules.registerCastingRule(STRING, CastingAnyString.INSTANCE); + + if (followCasters) { + constructExpansionCastingRules(environment, rules); + } + } + @Override public boolean canCastExplicit(ZenType type, IEnvironmentGlobal environment) { return true; @@ -282,26 +117,14 @@ public class ZenTypeAny extends ZenType { public boolean isPointer() { return true; } - - @Override - public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType toType) { - if (CASTERS.containsKey(toType.getName())) { - CASTERS.get(toType.getName()).compile(environment.getOutput()); - } else { - if (!compileCastExpansion(position, environment, toType)) { - environment.getOutput().constant(toType); - environment.getOutput().invokeInterface(IAny.class, "as", Class.class, Object.class); - } - } - } @Override public Expression unary(ZenPosition position, IEnvironmentGlobal environment, Expression value, OperatorType operator) { switch (operator) { case NEG: - return new ExpressionJavaCallVirtual(position, METHOD_NEG, value); + return new ExpressionCallVirtual(position, environment, METHOD_NEG, value); case NOT: - return new ExpressionJavaCallVirtual(position, METHOD_NOT, value); + return new ExpressionCallVirtual(position, environment, METHOD_NOT, value); default: return new ExpressionInvalid(position, ZenTypeAny.INSTANCE); } @@ -311,33 +134,33 @@ public class ZenTypeAny extends ZenType { public Expression binary(ZenPosition position, IEnvironmentGlobal environment, Expression left, Expression right, OperatorType operator) { switch (operator) { case ADD: - return new ExpressionJavaCallVirtual(position, METHOD_ADD, left, right.cast(position, environment, ANY)); + return new ExpressionCallVirtual(position, environment, METHOD_ADD, left, right.cast(position, environment, ANY)); case CAT: - return new ExpressionJavaCallVirtual(position, METHOD_CAT, left, right.cast(position, environment, ANY)); + return new ExpressionCallVirtual(position, environment, METHOD_CAT, left, right.cast(position, environment, ANY)); case SUB: - return new ExpressionJavaCallVirtual(position, METHOD_SUB, left, right.cast(position, environment, ANY)); + return new ExpressionCallVirtual(position, environment, METHOD_SUB, left, right.cast(position, environment, ANY)); case MUL: - return new ExpressionJavaCallVirtual(position, METHOD_MUL, left, right.cast(position, environment, ANY)); + return new ExpressionCallVirtual(position, environment, METHOD_MUL, left, right.cast(position, environment, ANY)); case DIV: - return new ExpressionJavaCallVirtual(position, METHOD_DIV, left, right.cast(position, environment, ANY)); + return new ExpressionCallVirtual(position, environment, METHOD_DIV, left, right.cast(position, environment, ANY)); case MOD: - return new ExpressionJavaCallVirtual(position, METHOD_MOD, left, right.cast(position, environment, ANY)); + return new ExpressionCallVirtual(position, environment, METHOD_MOD, left, right.cast(position, environment, ANY)); case AND: - return new ExpressionJavaCallVirtual(position, METHOD_AND, left, right.cast(position, environment, ANY)); + return new ExpressionCallVirtual(position, environment, METHOD_AND, left, right.cast(position, environment, ANY)); case OR: - return new ExpressionJavaCallVirtual(position, METHOD_OR, left, right.cast(position, environment, ANY)); + return new ExpressionCallVirtual(position, environment, METHOD_OR, left, right.cast(position, environment, ANY)); case XOR: - return new ExpressionJavaCallVirtual(position, METHOD_XOR, left, right.cast(position, environment, ANY)); + return new ExpressionCallVirtual(position, environment, METHOD_XOR, left, right.cast(position, environment, ANY)); case CONTAINS: - return new ExpressionJavaCallVirtual(position, METHOD_CONTAINS, left, right.cast(position, environment, ANY)); + return new ExpressionCallVirtual(position, environment, METHOD_CONTAINS, left, right.cast(position, environment, ANY)); case INDEXGET: - return new ExpressionJavaCallVirtual(position, METHOD_INDEXGET, left, right.cast(position, environment, ANY)); + return new ExpressionCallVirtual(position, environment, METHOD_INDEXGET, left, right.cast(position, environment, ANY)); case RANGE: - return new ExpressionJavaCallVirtual(position, METHOD_RANGE, left, right.cast(position, environment, ANY)); + return new ExpressionCallVirtual(position, environment, METHOD_RANGE, left, right.cast(position, environment, ANY)); case COMPARE: - return new ExpressionJavaCallVirtual(position, METHOD_COMPARETO, left, right.cast(position, environment, ANY)); + return new ExpressionCallVirtual(position, environment, METHOD_COMPARETO, left, right.cast(position, environment, ANY)); case MEMBERGETTER: - return new ExpressionJavaCallVirtual(position, METHOD_MEMBERGET, left, right.cast(position, environment, STRING)); + return new ExpressionCallVirtual(position, environment, METHOD_MEMBERGET, left, right.cast(position, environment, STRING)); default: return new ExpressionInvalid(position, ANY); } @@ -347,9 +170,9 @@ public class ZenTypeAny extends ZenType { public Expression trinary(ZenPosition position, IEnvironmentGlobal environment, Expression first, Expression second, Expression third, OperatorType operator) { switch (operator) { case INDEXSET: - return new ExpressionJavaCallVirtual(position, METHOD_INDEXSET, first, second.cast(position, environment, ANY), third.cast(position, environment, ANY)); + return new ExpressionCallVirtual(position, environment, METHOD_INDEXSET, first, second.cast(position, environment, ANY), third.cast(position, environment, ANY)); case MEMBERSETTER: - return new ExpressionJavaCallVirtual(position, METHOD_MEMBERSET, first, second.cast(position, environment, STRING), third.cast(position, environment, ANY)); + return new ExpressionCallVirtual(position, environment, METHOD_MEMBERSET, first, second.cast(position, environment, STRING), third.cast(position, environment, ANY)); default: return new ExpressionInvalid(position, ANY); } @@ -357,9 +180,12 @@ public class ZenTypeAny extends ZenType { @Override public Expression compare(ZenPosition position, IEnvironmentGlobal environment, Expression left, Expression right, CompareType type) { - Expression comparator = JavaMethod - .get(environment, IAny.class, "compareTo", IAny.class) - .callVirtual(position, environment, left, right); + Expression comparator = new ExpressionCallVirtual( + position, + environment, + JavaMethod.get(environment, IAny.class, "compareTo", IAny.class), + left, + right); return new ExpressionCompareGeneric( position, @@ -369,20 +195,21 @@ public class ZenTypeAny extends ZenType { @Override public Expression call(ZenPosition position, IEnvironmentGlobal environment, Expression receiver, Expression... arguments) { - return JavaMethod - .get(environment, IAny.class, "call", IAny[].class) - .callVirtual(position, environment, receiver, arguments); + return new ExpressionCallVirtual( + position, + environment, + JavaMethod.get(environment, IAny.class, "call", IAny[].class), + receiver, + arguments); } @Override - public Expression cast(ZenPosition position, IEnvironmentGlobal environment, Expression value, ZenType type) { - if (type.equals(this)) return value; - - if (canCastExpansion(environment, type)) { - return castExpansion(position, environment, value, type); - } else { - return new ExpressionAs(position, value, type); + public ZenType[] predictCallTypes(int numArguments) { + ZenType[] result = new ZenType[numArguments]; + for (int i = 0; i < result.length; i++) { + result[i] = ANY; } + return result; } @Override diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeArray.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeArray.java index eef28d1..2f03025 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeArray.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeArray.java @@ -44,19 +44,6 @@ public abstract class ZenTypeArray extends ZenType { return name; } - @Override - public final boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { - if (equals(type) || canCastExpansion(environment, type)) { - return true; - } - - if (type instanceof ZenTypeArray) { - return base.canCastImplicit(((ZenTypeArray) type).base, environment); - } - - return false; - } - @Override public final boolean canCastExplicit(ZenType type, IEnvironmentGlobal environment) { return equals(type) || canCastExpansion(environment, type); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeArrayBasic.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeArrayBasic.java index 43516f4..8df9d0e 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeArrayBasic.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeArrayBasic.java @@ -1,7 +1,5 @@ package stanhebben.zenscript.type; -import java.util.Arrays; -import java.util.List; import org.objectweb.asm.Label; import org.objectweb.asm.Type; import stanhebben.zenscript.compiler.IEnvironmentGlobal; @@ -11,6 +9,11 @@ import stanhebben.zenscript.expression.ExpressionArrayGet; import stanhebben.zenscript.expression.ExpressionArrayLength; import stanhebben.zenscript.expression.ExpressionArraySet; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.casting.CastingRuleArrayArray; +import stanhebben.zenscript.type.casting.CastingRuleArrayList; +import stanhebben.zenscript.type.casting.CastingRuleDelegateArray; +import stanhebben.zenscript.type.casting.ICastingRule; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; import stanhebben.zenscript.util.MethodOutput; import stanhebben.zenscript.util.ZenPosition; @@ -41,12 +44,32 @@ public class ZenTypeArrayBasic extends ZenTypeArray { } @Override - public Expression cast(ZenPosition position, IEnvironmentGlobal environment, Expression value, ZenType type) { - if (equals(type)) return value; - - return castExpansion(position, environment, value, type); + public ICastingRule getCastingRule(ZenType type, IEnvironmentGlobal environment) { + ICastingRule base = super.getCastingRule(type, environment); + if (base == null && getBaseType() == ANY && type instanceof ZenTypeArray) { + ZenType toBaseType = ((ZenTypeArray)type).getBaseType(); + if (type instanceof ZenTypeArrayBasic) { + return new CastingRuleArrayArray(ANY.getCastingRule(toBaseType, environment), this, (ZenTypeArrayBasic) type); + } else if (type instanceof ZenTypeArrayList) { + return new CastingRuleArrayList(ANY.getCastingRule(toBaseType, environment), this, (ZenTypeArrayList) type); + } else { + throw new RuntimeException("Invalid array type: " + type); + } + } else { + return base; + } } - + + @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + ICastingRuleDelegate arrayRules = new CastingRuleDelegateArray(rules, this); + getBaseType().constructCastingRules(environment, arrayRules, followCasters); + + if (followCasters) { + constructExpansionCastingRules(environment, rules); + } + } + @Override public IZenIterator makeIterator(int numValues, IEnvironmentMethod methodOutput) { if (numValues == 1) { @@ -71,7 +94,7 @@ public class ZenTypeArrayBasic extends ZenTypeArray { @Override public Class toJavaClass() { try { - return Class.forName("[" + getBaseType().toJavaClass().getName()); + return Class.forName("[L" + getBaseType().toJavaClass().getName() + ";"); } catch (ClassNotFoundException ex) { throw new RuntimeException(ex); } @@ -81,68 +104,7 @@ public class ZenTypeArrayBasic extends ZenTypeArray { public String getSignature() { return "[" + getBaseType().getSignature(); } - - @Override - public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType toClass) { - MethodOutput output = environment.getOutput(); - - if (compileCastExpansion(position, environment, toClass)) { - // OK - } else if (toClass instanceof ZenTypeArrayList) { - // convert array to list - // Arrays.asList(value); - output.invokeStatic(Arrays.class, "asList", List.class, Object[].class); - } else if (toClass instanceof ZenTypeArrayBasic) { - // convert elements - if (toClass.equals(this)) { - // do nothing - } else { - ZenType component = ((ZenTypeArrayBasic) toClass).getBaseType(); - Type componentType = component.toASMType(); - - int result = output.local(componentType); - - output.dup(); - output.arrayLength(); - output.newArray(componentType); - output.storeObject(result); - - output.iConst0(); - - Label lbl = new Label(); - output.label(lbl); - - // stack: original index - output.dupX1(); - output.dupX1(); - output.arrayLoad(componentType); - - // stack: original index value - getBaseType().compileCast(position, environment, toClass); - - output.loadObject(result); - output.dupX2(); - output.dupX2(); - output.arrayStore(componentType); - output.pop(); - - // stack: original index - output.iConst1(); - output.iAdd(); - output.dupX1(); - output.arrayLength(); - output.ifICmpGE(lbl); - - output.pop(); - output.pop(); - - output.loadObject(result); - } - } else { - // TODO: error - } - } - + @Override public IPartialExpression getMemberLength(ZenPosition position, IEnvironmentGlobal environment, IPartialExpression value) { return new ExpressionArrayLength(position, value.eval(environment)); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeArrayList.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeArrayList.java index b7393d0..9e90de9 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeArrayList.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeArrayList.java @@ -7,15 +7,15 @@ package stanhebben.zenscript.type; import java.util.List; -import org.objectweb.asm.Label; import org.objectweb.asm.Type; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.casting.CastingRuleDelegateList; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; import stanhebben.zenscript.type.iterator.IteratorIterable; import stanhebben.zenscript.type.iterator.IteratorList; -import stanhebben.zenscript.util.MethodOutput; import stanhebben.zenscript.util.ZenPosition; import static stanhebben.zenscript.util.ZenTypeUtil.signature; @@ -38,12 +38,15 @@ public class ZenTypeArrayList extends ZenTypeArray { } @Override - public Expression cast(ZenPosition position, IEnvironmentGlobal environment, Expression value, ZenType type) { - if (equals(type)) return value; + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + ICastingRuleDelegate arrayRules = new CastingRuleDelegateList(rules, this); + getBaseType().constructCastingRules(environment, arrayRules, followCasters); - return castExpansion(position, environment, value, type); + if (followCasters) { + constructExpansionCastingRules(environment, rules); + } } - + @Override public IZenIterator makeIterator(int numValues, IEnvironmentMethod methodOutput) { if (numValues == 1) { @@ -74,74 +77,16 @@ public class ZenTypeArrayList extends ZenTypeArray { public String getSignature() { return signature(List.class); } - - @Override - public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { - MethodOutput output = environment.getOutput(); - - if (equals(type)) { - return; - } - - if (compileCastExpansion(position, environment, type)) { - // OK - } else if (type instanceof ZenTypeArrayList) { - // TODO: implement - } else if (type instanceof ZenTypeArrayBasic) { - // convert elements - ZenType component = ((ZenTypeArrayBasic) type).getBaseType(); - Type componentType = component.toASMType(); - Type baseType = getBaseType().toASMType(); - - int result = output.local(componentType); - - output.dup(); - output.arrayLength(); - output.newArray(baseType); - output.storeObject(result); - - output.iConst0(); - - Label lbl = new Label(); - output.label(lbl); - - // stack: original index - output.dupX1(); - output.dupX1(); - output.arrayLoad(componentType); - - // stack: original index value - getBaseType().compileCast(position, environment, type); - - output.loadObject(result); - output.dupX2(); - output.dupX2(); - output.arrayStore(baseType); - output.pop(); - - // stack: original index - output.iConst1(); - output.iAdd(); - output.dupX1(); - output.arrayLength(); - output.ifICmpGE(lbl); - - output.pop(); - output.pop(); - - output.loadObject(result); - } else { - // TODO: error - } - } - + @Override public Expression indexGet(ZenPosition position, IEnvironmentGlobal environment, Expression array, Expression index) { + // TODO: implement throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public Expression indexSet(ZenPosition position, IEnvironmentGlobal environment, Expression array, Expression index, Expression value) { + // TODO: implement throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeAssociative.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeAssociative.java index da43db9..9615d46 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeAssociative.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeAssociative.java @@ -22,6 +22,9 @@ import stanhebben.zenscript.expression.ExpressionMapSize; import stanhebben.zenscript.expression.ExpressionNull; import stanhebben.zenscript.expression.ExpressionString; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.casting.CastingRuleMap; +import stanhebben.zenscript.type.casting.ICastingRule; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; import stanhebben.zenscript.type.iterator.IteratorMap; import stanhebben.zenscript.type.iterator.IteratorMapKeys; import stanhebben.zenscript.util.ZenPosition; @@ -32,24 +35,39 @@ import static stanhebben.zenscript.util.ZenTypeUtil.signature; * @author Stanneke */ public class ZenTypeAssociative extends ZenType { - private final ZenType base; - private final ZenType key; + private final ZenType valueType; + private final ZenType keyType; private final String name; - public ZenTypeAssociative(ZenType base, ZenType key) { - this.base = base; - this.key = key; + public ZenTypeAssociative(ZenType valueType, ZenType keyType) { + this.valueType = valueType; + this.keyType = keyType; - name = base.getName() + "[" + key.getName() + "]"; + name = valueType.getName() + "[" + keyType.getName() + "]"; } public ZenType getValueType() { - return base; + return valueType; } public ZenType getKeyType() { - return key; + return keyType; + } + + @Override + public ICastingRule getCastingRule(ZenType type, IEnvironmentGlobal environment) { + ICastingRule base = super.getCastingRule(type, environment); + if (base == null && type instanceof ZenTypeAssociative && keyType == ANY && valueType == ANY) { + ZenTypeAssociative aType = (ZenTypeAssociative) type; + return new CastingRuleMap( + ANY.getCastingRule(aType.keyType, environment), + ANY.getCastingRule(aType.valueType, environment), + this, + aType); + } else { + return base; + } } @Override @@ -71,9 +89,9 @@ public class ZenTypeAssociative extends ZenType { @Override public Expression binary(ZenPosition position, IEnvironmentGlobal environment, Expression left, Expression right, OperatorType operator) { if (operator == OperatorType.CONTAINS) { - return new ExpressionMapContains(position, left, right.cast(position, environment, key)); + return new ExpressionMapContains(position, left, right.cast(position, environment, keyType)); } else if (operator == OperatorType.INDEXGET) { - return new ExpressionMapIndexGet(position, left, right.cast(position, environment, key)); + return new ExpressionMapIndexGet(position, left, right.cast(position, environment, keyType)); } else { Expression result = binaryExpansion(position, environment, left, right, operator); if (result == null) { @@ -91,8 +109,8 @@ public class ZenTypeAssociative extends ZenType { return new ExpressionMapIndexSet( position, first, - second.cast(position, environment, key), - third.cast(position, environment, base)); + second.cast(position, environment, keyType), + third.cast(position, environment, valueType)); } else { Expression result = trinaryExpansion(position, environment, first, second, third, operator); if (result == null) { @@ -119,16 +137,16 @@ public class ZenTypeAssociative extends ZenType { public IPartialExpression getMember(ZenPosition position, IEnvironmentGlobal environment, IPartialExpression value, String name) { if (name.equals("length")) { return new ExpressionMapSize(position, value.eval(environment)); - } else if (STRING.canCastImplicit(key, environment)) { + } else if (STRING.canCastImplicit(keyType, environment)) { return new ExpressionMapIndexGet( position, value.eval(environment), - new ExpressionString(position, name).cast(position, environment, key)); + new ExpressionString(position, name).cast(position, environment, keyType)); } else { IPartialExpression result = memberExpansion(position, environment, value.eval(environment), name); if (result == null) { environment.error(position, "this array is not indexable with strings"); - return new ExpressionInvalid(position, base); + return new ExpressionInvalid(position, valueType); } else { return result; } @@ -153,14 +171,12 @@ public class ZenTypeAssociative extends ZenType { } @Override - public Expression cast(ZenPosition position, IEnvironmentGlobal environment, Expression value, ZenType type) { - if (type == this) { - return value; + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + if (followCasters) { + constructExpansionCastingRules(environment, rules); } - - return castExpansion(position, environment, value, type); } - + @Override public IZenIterator makeIterator(int numValues, IEnvironmentMethod methodOutput) { if (numValues == 1) { @@ -172,11 +188,6 @@ public class ZenTypeAssociative extends ZenType { } } - @Override - public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { - return type == this || canCastAssociative(type, environment) || canCastExpansion(environment, type); - } - @Override public boolean canCastExplicit(ZenType type, IEnvironmentGlobal environment) { return type == this || canCastAssociative(type, environment) || canCastExpansion(environment, type); @@ -207,15 +218,6 @@ public class ZenTypeAssociative extends ZenType { return true; } - @Override - public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { - if (equals(type)) { - // nothing to do - } else if (!compileCastExpansion(position, environment, type)) { - environment.error(position, "cannot cast " + this + " to " + type); - } - } - @Override public String getName() { return name; diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeBool.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeBool.java index c40d410..f1ac3e3 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeBool.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeBool.java @@ -13,12 +13,14 @@ import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.ExpressionArithmeticBinary; import stanhebben.zenscript.expression.ExpressionArithmeticCompare; import stanhebben.zenscript.expression.ExpressionArithmeticUnary; -import stanhebben.zenscript.expression.ExpressionAs; import stanhebben.zenscript.expression.ExpressionBool; import stanhebben.zenscript.expression.ExpressionInvalid; import stanhebben.zenscript.expression.partial.IPartialExpression; import static stanhebben.zenscript.type.ZenType.BYTE; import static stanhebben.zenscript.type.ZenType.STRING; +import stanhebben.zenscript.type.casting.CastingRuleStaticMethod; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; +import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.AnyClassWriter; import static stanhebben.zenscript.util.AnyClassWriter.METHOD_ASBOOL; import static stanhebben.zenscript.util.AnyClassWriter.METHOD_ASBYTE; @@ -33,7 +35,6 @@ import static stanhebben.zenscript.util.ZenTypeUtil.signature; import stanhebben.zenscript.value.IAny; public class ZenTypeBool extends ZenType { - //private static final JavaMethod BOOL_TOSTRING = JavaMethod.get(EMPTY_REGISTRY, Boolean.class, "toString", boolean.class); private static final String ANY_NAME = "any/AnyBool"; private static final String ANY_NAME_2 = "any.AnyBool"; private static final String ANY_NAME_DESC = "Lany/AnyBool;"; @@ -44,18 +45,31 @@ public class ZenTypeBool extends ZenType { public IZenIterator makeIterator(int numValues, IEnvironmentMethod methodOutput) { return null; } - + @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + rules.registerCastingRule(STRING, new CastingRuleStaticMethod(BOOL_TOSTRING_STATIC)); + rules.registerCastingRule(BOOLOBJECT, new CastingRuleStaticMethod(BOOL_VALUEOF)); + rules.registerCastingRule(ANY, new CastingRuleStaticMethod(JavaMethod.getStatic( + getAnyClassName(environment), "valueOf", ANY, BOOL + ))); + + if (followCasters) { + constructExpansionCastingRules(environment, rules); + } + } + + /*@Override public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { return type == BOOL || type == ANY || type == ZenTypeString.INSTANCE || canCastExpansion(environment, type); - } + }*/ @Override public boolean canCastExplicit(ZenType type, IEnvironmentGlobal environment) { - return type == BOOL || type == ANY || type == ZenTypeString.INSTANCE || canCastExpansion(environment, type); + return canCastImplicit(type, environment); } - @Override + /*@Override public Expression cast(ZenPosition position, IEnvironmentGlobal environment, Expression value, ZenType type) { if (type == BOOL || type == ZenTypeBoolObject.INSTANCE || type == STRING || type == ANY) { return new ExpressionAs(position, value, type); @@ -64,7 +78,7 @@ public class ZenTypeBool extends ZenType { } else { return new ExpressionAs(position, value, type); } - } + }*/ @Override public Class toJavaClass() { @@ -140,7 +154,7 @@ public class ZenTypeBool extends ZenType { environment.error(position, "cannot call a boolean value"); return new ExpressionInvalid(position, ZenTypeAny.INSTANCE); } - + @Override public IPartialExpression getMember(ZenPosition position, IEnvironmentGlobal environment, IPartialExpression value, String name) { IPartialExpression result = memberExpansion(position, environment, value.eval(environment), name); @@ -168,7 +182,7 @@ public class ZenTypeBool extends ZenType { return false; } - @Override + /*@Override public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { if (type == this) { // nothing to do @@ -181,7 +195,7 @@ public class ZenTypeBool extends ZenType { } else if (!compileCastExpansion(position, environment, type)) { environment.error(position, "Cannot compile bool to " + type); } - } + }*/ @Override public String getName() { @@ -321,7 +335,7 @@ public class ZenTypeBool extends ZenType { getValue(output); output.invokeVirtual(StringBuilder.class, "append", StringBuilder.class, boolean.class); output.loadObject(1); - output.invoke(METHOD_ASSTRING); + METHOD_ASSTRING.invokeVirtual(output); output.invokeVirtual(StringBuilder.class, "append", StringBuilder.class, String.class); output.invokeVirtual(StringBuilder.class, "toString", String.class); output.invokeStatic(STRING.getAnyClassName(environment), "valueOf", "(Ljava/lang/String;)" + signature(IAny.class)); @@ -349,7 +363,7 @@ public class ZenTypeBool extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASBOOL); + METHOD_ASBOOL.invokeVirtual(output); output.iAnd(); valueOf(output); output.returnObject(); @@ -361,7 +375,7 @@ public class ZenTypeBool extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASBOOL); + METHOD_ASBOOL.invokeVirtual(output); output.iOr(); valueOf(output); output.returnObject(); @@ -373,7 +387,7 @@ public class ZenTypeBool extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASBYTE); + METHOD_ASBYTE.invokeVirtual(output); output.iXor(); valueOf(output); output.returnObject(); @@ -388,7 +402,7 @@ public class ZenTypeBool extends ZenType { public void defineCompareTo(MethodOutput output) { getValue(output); output.loadObject(1); - output.invoke(METHOD_ASBOOL); + METHOD_ASBOOL.invokeVirtual(output); output.iSub(); output.returnInt(); } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeBoolObject.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeBoolObject.java index 61a9449..12ebc3e 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeBoolObject.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeBoolObject.java @@ -6,22 +6,22 @@ package stanhebben.zenscript.type; -import org.objectweb.asm.Label; import org.objectweb.asm.Type; import stanhebben.zenscript.annotations.CompareType; import stanhebben.zenscript.annotations.OperatorType; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; -import stanhebben.zenscript.expression.ExpressionAs; import stanhebben.zenscript.expression.ExpressionNull; import stanhebben.zenscript.expression.partial.IPartialExpression; import static stanhebben.zenscript.type.ZenType.BOOL; -import static stanhebben.zenscript.type.ZenType.STRING; -import stanhebben.zenscript.util.MethodOutput; +import stanhebben.zenscript.type.casting.CastingRuleNullableStaticMethod; +import stanhebben.zenscript.type.casting.CastingRuleNullableVirtualMethod; +import stanhebben.zenscript.type.casting.CastingRuleVirtualMethod; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; +import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.ZenPosition; import static stanhebben.zenscript.util.ZenTypeUtil.signature; -import stanhebben.zenscript.value.IAny; /** * @@ -66,20 +66,32 @@ public class ZenTypeBoolObject extends ZenType { public Expression call(ZenPosition position, IEnvironmentGlobal environment, Expression receiver, Expression... arguments) { return BOOL.call(position, environment, receiver.cast(position, environment, BOOL), arguments); } - + @Override public IZenIterator makeIterator(int numValues, IEnvironmentMethod methodOutput) { return BOOL.makeIterator(numValues, methodOutput); } @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + rules.registerCastingRule(BOOL, new CastingRuleVirtualMethod(BOOL_VALUE)); + rules.registerCastingRule(STRING, new CastingRuleNullableVirtualMethod(BOOL, BOOL_TOSTRING)); + rules.registerCastingRule(ANY, new CastingRuleNullableStaticMethod(JavaMethod.getStatic( + BOOL.getAnyClassName(environment), + "valueOf", + ANY, + BOOL + ), new CastingRuleVirtualMethod(BOOL_VALUE))); + } + + /*@Override public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { return BOOL.canCastImplicit(type, environment); - } + }*/ @Override public boolean canCastExplicit(ZenType type, IEnvironmentGlobal environment) { - return BOOL.canCastExplicit(type, environment); + return canCastImplicit(type, environment); } @Override @@ -107,7 +119,7 @@ public class ZenTypeBoolObject extends ZenType { return true; } - @Override + /*@Override public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { if (type == this) { // nothing to do @@ -135,7 +147,7 @@ public class ZenTypeBoolObject extends ZenType { environment.getOutput().invokeVirtual(Boolean.class, "booleanValue", boolean.class); BOOL.compileCast(position, environment, type); } - } + }*/ @Override public String getName() { @@ -147,7 +159,7 @@ public class ZenTypeBoolObject extends ZenType { return BOOL.getAnyClassName(environment); } - @Override + /*@Override public Expression cast(ZenPosition position, IEnvironmentGlobal environment, Expression value, ZenType type) { if (type == BOOL || type == ZenTypeBoolObject.INSTANCE || type == STRING) { return new ExpressionAs(position, value, type); @@ -156,7 +168,7 @@ public class ZenTypeBoolObject extends ZenType { } else { return new ExpressionAs(position, value, type); } - } + }*/ @Override public Expression defaultValue(ZenPosition position) { diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeByte.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeByte.java index 66a7291..e39fc59 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeByte.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeByte.java @@ -13,11 +13,17 @@ import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.ExpressionArithmeticBinary; import stanhebben.zenscript.expression.ExpressionArithmeticCompare; import stanhebben.zenscript.expression.ExpressionArithmeticUnary; -import stanhebben.zenscript.expression.ExpressionAs; import stanhebben.zenscript.expression.ExpressionInt; import stanhebben.zenscript.expression.ExpressionInvalid; import stanhebben.zenscript.expression.partial.IPartialExpression; import static stanhebben.zenscript.type.ZenTypeAny.*; +import stanhebben.zenscript.type.casting.CastingRuleI2D; +import stanhebben.zenscript.type.casting.CastingRuleI2F; +import stanhebben.zenscript.type.casting.CastingRuleI2L; +import stanhebben.zenscript.type.casting.CastingRuleNone; +import stanhebben.zenscript.type.casting.CastingRuleStaticMethod; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; +import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.AnyClassWriter; import static stanhebben.zenscript.util.AnyClassWriter.METHOD_ASBYTE; import static stanhebben.zenscript.util.AnyClassWriter.METHOD_ASSTRING; @@ -44,6 +50,28 @@ public class ZenTypeByte extends ZenType { } @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + rules.registerCastingRule(BYTEOBJECT, new CastingRuleStaticMethod(BYTE_VALUEOF)); + rules.registerCastingRule(SHORT, new CastingRuleNone(BYTE, SHORT)); + rules.registerCastingRule(SHORTOBJECT, new CastingRuleStaticMethod(SHORT_VALUEOF)); + rules.registerCastingRule(INT, new CastingRuleNone(BYTE, INT)); + rules.registerCastingRule(INTOBJECT, new CastingRuleStaticMethod(INT_VALUEOF)); + rules.registerCastingRule(LONG, new CastingRuleI2L(null)); + rules.registerCastingRule(LONGOBJECT, new CastingRuleStaticMethod(LONG_VALUEOF, new CastingRuleI2L(null))); + rules.registerCastingRule(FLOAT, new CastingRuleI2F(null)); + rules.registerCastingRule(FLOATOBJECT, new CastingRuleStaticMethod(FLOAT_VALUEOF, new CastingRuleI2F(null))); + rules.registerCastingRule(DOUBLE, new CastingRuleI2D(null)); + rules.registerCastingRule(DOUBLEOBJECT, new CastingRuleStaticMethod(DOUBLE_VALUEOF, new CastingRuleI2D(null))); + + rules.registerCastingRule(STRING, new CastingRuleStaticMethod(BYTE_TOSTRING_STATIC)); + rules.registerCastingRule(ANY, new CastingRuleStaticMethod(JavaMethod.getStatic(getAnyClassName(environment), "valueOf", ANY, BYTE))); + + if (followCasters) { + constructExpansionCastingRules(environment, rules); + } + } + + /*@Override public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { int itype = type.getNumberType(); return itype != 0 @@ -69,7 +97,7 @@ public class ZenTypeByte extends ZenType { } else { return new ExpressionAs(position, value, type); } - } + }*/ @Override public Class toJavaClass() { @@ -112,7 +140,7 @@ public class ZenTypeByte extends ZenType { return false; } - @Override + /*@Override public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { MethodOutput output = environment.getOutput(); @@ -150,7 +178,7 @@ public class ZenTypeByte extends ZenType { } else if (!compileCastExpansion(position, environment, type)) { environment.error(position, "cannot cast " + this + " to " + type); } - } + }*/ @Override public Expression unary(ZenPosition position, IEnvironmentGlobal environment, Expression value, OperatorType operator) { @@ -316,7 +344,7 @@ public class ZenTypeByte extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASBYTE); + METHOD_ASBYTE.invokeVirtual(output); output.iAdd(); output.invokeSpecial(ANY_NAME, "", "(B)V"); output.returnObject(); @@ -328,7 +356,7 @@ public class ZenTypeByte extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASBYTE); + METHOD_ASBYTE.invokeVirtual(output); output.iSub(); output.invokeSpecial(ANY_NAME, "", "(B)V"); output.returnObject(); @@ -346,7 +374,7 @@ public class ZenTypeByte extends ZenType { getValue(output); output.invokeVirtual(StringBuilder.class, "append", StringBuilder.class, int.class); output.loadObject(1); - output.invoke(METHOD_ASSTRING); + METHOD_ASSTRING.invokeVirtual(output); output.invokeVirtual(StringBuilder.class, "append", StringBuilder.class, String.class); output.invokeVirtual(StringBuilder.class, "toString", String.class); output.invokeStatic(STRING.getAnyClassName(environment), "valueOf", "(Ljava/lang/String;)" + signature(IAny.class)); @@ -359,7 +387,7 @@ public class ZenTypeByte extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASBYTE); + METHOD_ASBYTE.invokeVirtual(output); output.iMul(); output.invokeSpecial(ANY_NAME, "", "(B)V"); output.returnObject(); @@ -371,7 +399,7 @@ public class ZenTypeByte extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASBYTE); + METHOD_ASBYTE.invokeVirtual(output); output.iDiv(); output.invokeSpecial(ANY_NAME, "", "(B)V"); output.returnObject(); @@ -383,7 +411,7 @@ public class ZenTypeByte extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASBYTE); + METHOD_ASBYTE.invokeVirtual(output); output.iRem(); output.invokeSpecial(ANY_NAME, "", "(B)V"); output.returnObject(); @@ -395,7 +423,7 @@ public class ZenTypeByte extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASBYTE); + METHOD_ASBYTE.invokeVirtual(output); output.iAnd(); output.invokeSpecial(ANY_NAME, "", "(B)V"); output.returnObject(); @@ -407,7 +435,7 @@ public class ZenTypeByte extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASBYTE); + METHOD_ASBYTE.invokeVirtual(output); output.iOr(); output.invokeSpecial(ANY_NAME, "", "(B)V"); output.returnObject(); @@ -419,7 +447,7 @@ public class ZenTypeByte extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASBYTE); + METHOD_ASBYTE.invokeVirtual(output); output.iXor(); output.invokeSpecial(ANY_NAME, "", "(B)V"); output.returnObject(); @@ -436,7 +464,7 @@ public class ZenTypeByte extends ZenType { public void defineCompareTo(MethodOutput output) { getValue(output); output.loadObject(1); - output.invoke(METHOD_ASBYTE); + METHOD_ASBYTE.invokeVirtual(output); output.iSub(); output.returnInt(); } @@ -586,7 +614,7 @@ public class ZenTypeByte extends ZenType { getValue(output); output.loadObject(1); - output.invoke(METHOD_ASBYTE); + METHOD_ASBYTE.invokeVirtual(output); output.ifICmpNE(lblNope); output.iConst1(); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeByteObject.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeByteObject.java index 0062e0d..538362f 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeByteObject.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeByteObject.java @@ -6,23 +6,22 @@ package stanhebben.zenscript.type; -import org.objectweb.asm.Label; import org.objectweb.asm.Type; import stanhebben.zenscript.annotations.CompareType; import stanhebben.zenscript.annotations.OperatorType; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; -import stanhebben.zenscript.expression.ExpressionAs; import stanhebben.zenscript.expression.ExpressionNull; import stanhebben.zenscript.expression.partial.IPartialExpression; import static stanhebben.zenscript.type.ZenType.ANY; -import static stanhebben.zenscript.type.ZenType.BOOL; -import static stanhebben.zenscript.type.ZenType.STRING; -import stanhebben.zenscript.util.MethodOutput; +import stanhebben.zenscript.type.casting.CastingRuleNullableStaticMethod; +import stanhebben.zenscript.type.casting.CastingRuleNullableVirtualMethod; +import stanhebben.zenscript.type.casting.CastingRuleVirtualMethod; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; +import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.ZenPosition; import static stanhebben.zenscript.util.ZenTypeUtil.signature; -import stanhebben.zenscript.value.IAny; /** * @@ -74,6 +73,40 @@ public class ZenTypeByteObject extends ZenType { } @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + rules.registerCastingRule(BYTE, new CastingRuleVirtualMethod(BYTE_VALUE)); + rules.registerCastingRule(SHORT, new CastingRuleVirtualMethod(SHORT_VALUE)); + rules.registerCastingRule(SHORTOBJECT, new CastingRuleNullableStaticMethod( + SHORT_VALUEOF, + new CastingRuleVirtualMethod(SHORT_VALUE))); + rules.registerCastingRule(INT, new CastingRuleVirtualMethod(INT_VALUE)); + rules.registerCastingRule(INTOBJECT, new CastingRuleNullableStaticMethod( + INT_VALUEOF, + new CastingRuleVirtualMethod(INT_VALUE))); + rules.registerCastingRule(LONG, new CastingRuleVirtualMethod(LONG_VALUE)); + rules.registerCastingRule(LONGOBJECT, new CastingRuleNullableStaticMethod( + LONG_VALUEOF, + new CastingRuleVirtualMethod(LONG_VALUE))); + rules.registerCastingRule(FLOAT, new CastingRuleVirtualMethod(FLOAT_VALUE)); + rules.registerCastingRule(FLOATOBJECT, new CastingRuleNullableStaticMethod( + FLOAT_VALUEOF, + new CastingRuleVirtualMethod(FLOAT_VALUE))); + rules.registerCastingRule(DOUBLE, new CastingRuleVirtualMethod(DOUBLE_VALUE)); + rules.registerCastingRule(DOUBLEOBJECT, new CastingRuleNullableStaticMethod( + DOUBLE_VALUEOF, + new CastingRuleVirtualMethod(DOUBLE_VALUE))); + + rules.registerCastingRule(STRING, new CastingRuleNullableVirtualMethod(BYTEOBJECT, BYTE_TOSTRING)); + rules.registerCastingRule(ANY, new CastingRuleNullableStaticMethod( + JavaMethod.getStatic(getAnyClassName(environment), "valueOf", ANY, BYTE), + new CastingRuleVirtualMethod(BYTE_VALUE))); + + if (followCasters) { + constructExpansionCastingRules(environment, rules); + } + } + + /*@Override public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { return BYTE.canCastImplicit(type, environment); } @@ -92,7 +125,7 @@ public class ZenTypeByteObject extends ZenType { @Override public boolean canCastExplicit(ZenType type, IEnvironmentGlobal environment) { return BYTE.canCastExplicit(type, environment); - } + }*/ @Override public Class toJavaClass() { @@ -119,7 +152,7 @@ public class ZenTypeByteObject extends ZenType { return true; } - @Override + /*@Override public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { if (type == this) { // nothing to do @@ -147,7 +180,7 @@ public class ZenTypeByteObject extends ZenType { environment.getOutput().invokeVirtual(Byte.class, "byteValue", byte.class); BYTE.compileCast(position, environment, type); } - } + }*/ @Override public String getName() { diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeDouble.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeDouble.java index c5447e1..1a8600b 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeDouble.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeDouble.java @@ -13,13 +13,23 @@ import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.ExpressionArithmeticBinary; import stanhebben.zenscript.expression.ExpressionArithmeticCompare; import stanhebben.zenscript.expression.ExpressionArithmeticUnary; -import stanhebben.zenscript.expression.ExpressionAs; import stanhebben.zenscript.expression.ExpressionFloat; import stanhebben.zenscript.expression.ExpressionInvalid; import stanhebben.zenscript.expression.partial.IPartialExpression; import static stanhebben.zenscript.type.ZenType.ANY; +import static stanhebben.zenscript.type.ZenType.BYTE; +import static stanhebben.zenscript.type.ZenType.BYTEOBJECT; +import static stanhebben.zenscript.type.ZenType.BYTE_VALUEOF; import static stanhebben.zenscript.type.ZenType.FLOAT; import static stanhebben.zenscript.type.ZenType.STRING; +import stanhebben.zenscript.type.casting.CastingRuleD2F; +import stanhebben.zenscript.type.casting.CastingRuleD2I; +import stanhebben.zenscript.type.casting.CastingRuleD2L; +import stanhebben.zenscript.type.casting.CastingRuleI2B; +import stanhebben.zenscript.type.casting.CastingRuleI2S; +import stanhebben.zenscript.type.casting.CastingRuleStaticMethod; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; +import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.AnyClassWriter; import static stanhebben.zenscript.util.AnyClassWriter.METHOD_ASDOUBLE; import static stanhebben.zenscript.util.AnyClassWriter.METHOD_ASSTRING; @@ -47,6 +57,28 @@ public class ZenTypeDouble extends ZenType { } @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + rules.registerCastingRule(BYTE, new CastingRuleI2B(new CastingRuleD2I(null))); + rules.registerCastingRule(BYTEOBJECT, new CastingRuleStaticMethod(BYTE_VALUEOF, new CastingRuleI2B(new CastingRuleD2I(null)))); + rules.registerCastingRule(SHORT, new CastingRuleI2S(new CastingRuleD2I(null))); + rules.registerCastingRule(SHORTOBJECT, new CastingRuleStaticMethod(SHORT_VALUEOF, new CastingRuleI2S(new CastingRuleD2I(null)))); + rules.registerCastingRule(INT, new CastingRuleD2I(null)); + rules.registerCastingRule(INTOBJECT, new CastingRuleStaticMethod(INT_VALUEOF, new CastingRuleD2I(null))); + rules.registerCastingRule(LONG, new CastingRuleD2L(null)); + rules.registerCastingRule(LONGOBJECT, new CastingRuleStaticMethod(LONG_VALUEOF, new CastingRuleD2L(null))); + rules.registerCastingRule(FLOAT, new CastingRuleD2F(null)); + rules.registerCastingRule(FLOATOBJECT, new CastingRuleStaticMethod(FLOAT_VALUEOF, new CastingRuleD2F(null))); + rules.registerCastingRule(DOUBLEOBJECT, new CastingRuleStaticMethod(DOUBLE_VALUEOF)); + + rules.registerCastingRule(STRING, new CastingRuleStaticMethod(DOUBLE_TOSTRING_STATIC)); + rules.registerCastingRule(ANY, new CastingRuleStaticMethod(JavaMethod.getStatic(getAnyClassName(environment), "valueOf", ANY, DOUBLE))); + + if (followCasters) { + constructExpansionCastingRules(environment, rules); + } + } + + /*@Override public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { return (type.getNumberType() != 0 && type.getNumberType() >= NUM_FLOAT) || type == STRING @@ -71,7 +103,7 @@ public class ZenTypeDouble extends ZenType { } else { return new ExpressionAs(position, value, type); } - } + }*/ @Override public Type toASMType() { @@ -114,7 +146,7 @@ public class ZenTypeDouble extends ZenType { return false; } - @Override + /*@Override public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { MethodOutput output = environment.getOutput(); @@ -158,7 +190,7 @@ public class ZenTypeDouble extends ZenType { } else if (!compileCastExpansion(position, environment, type)) { environment.error(position, "cannot cast " + this + " to " + type); } - } + }*/ @Override public Expression unary(ZenPosition position, IEnvironmentGlobal environment, Expression value, OperatorType operator) { @@ -324,7 +356,7 @@ public class ZenTypeDouble extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASDOUBLE); + METHOD_ASDOUBLE.invokeVirtual(output); output.dAdd(); output.invokeSpecial(ANY_NAME, "", "(D)V"); output.returnObject(); @@ -336,7 +368,7 @@ public class ZenTypeDouble extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASDOUBLE); + METHOD_ASDOUBLE.invokeVirtual(output); output.dSub(); output.invokeSpecial(ANY_NAME, "", "(D)V"); output.returnObject(); @@ -354,7 +386,7 @@ public class ZenTypeDouble extends ZenType { getValue(output); output.invokeVirtual(StringBuilder.class, "append", StringBuilder.class, double.class); output.loadObject(1); - output.invoke(METHOD_ASSTRING); + METHOD_ASSTRING.invokeVirtual(output); output.invokeVirtual(StringBuilder.class, "append", StringBuilder.class, String.class); output.invokeVirtual(StringBuilder.class, "toString", String.class); output.invokeStatic(STRING.getAnyClassName(environment), "valueOf", "(Ljava/lang/String;)" + signature(IAny.class)); @@ -367,7 +399,7 @@ public class ZenTypeDouble extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASDOUBLE); + METHOD_ASDOUBLE.invokeVirtual(output); output.dMul(); output.invokeSpecial(ANY_NAME, "", "(D)V"); output.returnObject(); @@ -379,7 +411,7 @@ public class ZenTypeDouble extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASDOUBLE); + METHOD_ASDOUBLE.invokeVirtual(output); output.dDiv(); output.invokeSpecial(ANY_NAME, "", "(D)V"); output.returnObject(); @@ -391,7 +423,7 @@ public class ZenTypeDouble extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASDOUBLE); + METHOD_ASDOUBLE.invokeVirtual(output); output.dRem(); output.invokeSpecial(ANY_NAME, "", "(D)V"); output.returnObject(); @@ -422,7 +454,7 @@ public class ZenTypeDouble extends ZenType { // return Double.compare(x, y) getValue(output); output.loadObject(1); - output.invoke(METHOD_ASDOUBLE); + METHOD_ASDOUBLE.invokeVirtual(output); output.invokeStatic(Float.class, "compare", int.class, double.class, double.class); output.returnInt(); } @@ -581,7 +613,7 @@ public class ZenTypeDouble extends ZenType { getValue(output); output.loadObject(1); - output.invoke(METHOD_ASDOUBLE); + METHOD_ASDOUBLE.invokeVirtual(output); output.dCmp(); output.ifNE(lblNope); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeDoubleObject.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeDoubleObject.java index 31904f8..f153b91 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeDoubleObject.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeDoubleObject.java @@ -6,23 +6,25 @@ package stanhebben.zenscript.type; -import org.objectweb.asm.Label; import org.objectweb.asm.Type; import stanhebben.zenscript.annotations.CompareType; import stanhebben.zenscript.annotations.OperatorType; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; -import stanhebben.zenscript.expression.ExpressionAs; import stanhebben.zenscript.expression.ExpressionNull; import stanhebben.zenscript.expression.partial.IPartialExpression; import static stanhebben.zenscript.type.ZenType.ANY; -import static stanhebben.zenscript.type.ZenType.BOOL; +import static stanhebben.zenscript.type.ZenType.BYTE; +import static stanhebben.zenscript.type.ZenType.BYTE_VALUE; import static stanhebben.zenscript.type.ZenType.STRING; -import stanhebben.zenscript.util.MethodOutput; +import stanhebben.zenscript.type.casting.CastingRuleNullableStaticMethod; +import stanhebben.zenscript.type.casting.CastingRuleNullableVirtualMethod; +import stanhebben.zenscript.type.casting.CastingRuleVirtualMethod; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; +import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.ZenPosition; import static stanhebben.zenscript.util.ZenTypeUtil.signature; -import stanhebben.zenscript.value.IAny; /** * @@ -74,6 +76,43 @@ public class ZenTypeDoubleObject extends ZenType { } @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + rules.registerCastingRule(BYTE, new CastingRuleVirtualMethod(BYTE_VALUE)); + rules.registerCastingRule(BYTEOBJECT, new CastingRuleNullableStaticMethod( + BYTE_VALUEOF, + new CastingRuleVirtualMethod(BYTE_VALUE))); + rules.registerCastingRule(SHORT, new CastingRuleVirtualMethod(SHORT_VALUE)); + rules.registerCastingRule(SHORTOBJECT, new CastingRuleNullableStaticMethod( + SHORT_VALUEOF, + new CastingRuleVirtualMethod(SHORT_VALUE))); + rules.registerCastingRule(INT, new CastingRuleVirtualMethod(INT_VALUE)); + rules.registerCastingRule(INTOBJECT, new CastingRuleNullableStaticMethod( + INT_VALUEOF, + new CastingRuleVirtualMethod(INT_VALUE))); + rules.registerCastingRule(LONG, new CastingRuleVirtualMethod(LONG_VALUE)); + rules.registerCastingRule(LONGOBJECT, new CastingRuleNullableStaticMethod( + LONG_VALUEOF, + new CastingRuleVirtualMethod(LONG_VALUE))); + rules.registerCastingRule(FLOAT, new CastingRuleVirtualMethod(FLOAT_VALUE)); + rules.registerCastingRule(FLOATOBJECT, new CastingRuleNullableStaticMethod( + FLOAT_VALUEOF, + new CastingRuleVirtualMethod(FLOAT_VALUE))); + rules.registerCastingRule(DOUBLE, new CastingRuleVirtualMethod(DOUBLE_VALUE)); + rules.registerCastingRule(DOUBLEOBJECT, new CastingRuleNullableStaticMethod( + DOUBLE_VALUEOF, + new CastingRuleVirtualMethod(DOUBLE_VALUE))); + + rules.registerCastingRule(STRING, new CastingRuleNullableVirtualMethod(DOUBLEOBJECT, DOUBLE_TOSTRING)); + rules.registerCastingRule(ANY, new CastingRuleNullableStaticMethod( + JavaMethod.getStatic(getAnyClassName(environment), "valueOf", ANY, DOUBLE), + new CastingRuleVirtualMethod(DOUBLE_VALUE))); + + if (followCasters) { + constructExpansionCastingRules(environment, rules); + } + } + + /*@Override public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { return DOUBLE.canCastImplicit(type, environment); } @@ -92,7 +131,7 @@ public class ZenTypeDoubleObject extends ZenType { } else { return new ExpressionAs(position, value, type); } - } + }*/ @Override public Class toJavaClass() { @@ -119,7 +158,7 @@ public class ZenTypeDoubleObject extends ZenType { return true; } - @Override + /*@Override public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { if (type == this) { // nothing to do @@ -147,7 +186,7 @@ public class ZenTypeDoubleObject extends ZenType { environment.getOutput().invokeVirtual(Double.class, "doubleValue", double.class); DOUBLE.compileCast(position, environment, type); } - } + }*/ @Override public String getName() { diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeFloat.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeFloat.java index edd98bf..0f26f95 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeFloat.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeFloat.java @@ -13,13 +13,23 @@ import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.ExpressionArithmeticBinary; import stanhebben.zenscript.expression.ExpressionArithmeticCompare; import stanhebben.zenscript.expression.ExpressionArithmeticUnary; -import stanhebben.zenscript.expression.ExpressionAs; import stanhebben.zenscript.expression.ExpressionFloat; import stanhebben.zenscript.expression.ExpressionInvalid; import stanhebben.zenscript.expression.partial.IPartialExpression; import static stanhebben.zenscript.type.ZenType.ANY; +import static stanhebben.zenscript.type.ZenType.BYTE; +import static stanhebben.zenscript.type.ZenType.BYTEOBJECT; +import static stanhebben.zenscript.type.ZenType.BYTE_VALUEOF; import static stanhebben.zenscript.type.ZenType.LONG; import static stanhebben.zenscript.type.ZenType.STRING; +import stanhebben.zenscript.type.casting.CastingRuleF2D; +import stanhebben.zenscript.type.casting.CastingRuleF2I; +import stanhebben.zenscript.type.casting.CastingRuleF2L; +import stanhebben.zenscript.type.casting.CastingRuleI2B; +import stanhebben.zenscript.type.casting.CastingRuleI2S; +import stanhebben.zenscript.type.casting.CastingRuleStaticMethod; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; +import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.AnyClassWriter; import static stanhebben.zenscript.util.AnyClassWriter.METHOD_ASFLOAT; import static stanhebben.zenscript.util.AnyClassWriter.METHOD_ASSTRING; @@ -47,6 +57,28 @@ public class ZenTypeFloat extends ZenType { } @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + rules.registerCastingRule(BYTE, new CastingRuleI2B(new CastingRuleF2I(null))); + rules.registerCastingRule(BYTEOBJECT, new CastingRuleStaticMethod(BYTE_VALUEOF, new CastingRuleI2B(new CastingRuleF2I(null)))); + rules.registerCastingRule(SHORT, new CastingRuleI2S(new CastingRuleF2I(null))); + rules.registerCastingRule(SHORTOBJECT, new CastingRuleStaticMethod(SHORT_VALUEOF, new CastingRuleI2S(new CastingRuleF2I(null)))); + rules.registerCastingRule(INT, new CastingRuleF2I(null)); + rules.registerCastingRule(INTOBJECT, new CastingRuleStaticMethod(INT_VALUEOF, new CastingRuleF2I(null))); + rules.registerCastingRule(LONG, new CastingRuleF2L(null)); + rules.registerCastingRule(LONGOBJECT, new CastingRuleStaticMethod(LONG_VALUEOF, new CastingRuleF2L(null))); + rules.registerCastingRule(FLOATOBJECT, new CastingRuleStaticMethod(FLOAT_VALUEOF)); + rules.registerCastingRule(DOUBLE, new CastingRuleF2D(null)); + rules.registerCastingRule(DOUBLEOBJECT, new CastingRuleStaticMethod(DOUBLE_VALUEOF, new CastingRuleF2D(null))); + + rules.registerCastingRule(STRING, new CastingRuleStaticMethod(FLOAT_TOSTRING_STATIC)); + rules.registerCastingRule(ANY, new CastingRuleStaticMethod(JavaMethod.getStatic(getAnyClassName(environment), "valueOf", ANY, FLOAT))); + + if (followCasters) { + constructExpansionCastingRules(environment, rules); + } + } + + /*@Override public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { return (type.getNumberType() != 0) || type == ZenTypeString.INSTANCE @@ -71,7 +103,7 @@ public class ZenTypeFloat extends ZenType { } else { return new ExpressionAs(position, value, type); } - } + }*/ @Override public Type toASMType() { @@ -109,7 +141,7 @@ public class ZenTypeFloat extends ZenType { return false; } - @Override + /*@Override public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { MethodOutput output = environment.getOutput(); @@ -153,7 +185,7 @@ public class ZenTypeFloat extends ZenType { } else if (!compileCastExpansion(position, environment, type)) { environment.error(position, "cannot cast " + this + " to " + type); } - } + }*/ @Override public Expression unary(ZenPosition position, IEnvironmentGlobal environment, Expression value, OperatorType operator) { @@ -319,7 +351,7 @@ public class ZenTypeFloat extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASFLOAT); + METHOD_ASFLOAT.invokeVirtual(output); output.fAdd(); output.invokeSpecial(ANY_NAME, "", "(F)V"); output.returnObject(); @@ -331,7 +363,7 @@ public class ZenTypeFloat extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASFLOAT); + METHOD_ASFLOAT.invokeVirtual(output); output.fSub(); output.invokeSpecial(ANY_NAME, "", "(F)V"); output.returnObject(); @@ -349,7 +381,7 @@ public class ZenTypeFloat extends ZenType { getValue(output); output.invokeVirtual(StringBuilder.class, "append", StringBuilder.class, float.class); output.loadObject(1); - output.invoke(METHOD_ASSTRING); + METHOD_ASSTRING.invokeVirtual(output); output.invokeVirtual(StringBuilder.class, "append", StringBuilder.class, String.class); output.invokeVirtual(StringBuilder.class, "toString", String.class); output.invokeStatic(STRING.getAnyClassName(environment), "valueOf", "(Ljava/lang/String;)" + signature(IAny.class)); @@ -362,7 +394,7 @@ public class ZenTypeFloat extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASFLOAT); + METHOD_ASFLOAT.invokeVirtual(output); output.fMul(); output.invokeSpecial(ANY_NAME, "", "(F)V"); output.returnObject(); @@ -374,7 +406,7 @@ public class ZenTypeFloat extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASFLOAT); + METHOD_ASFLOAT.invokeVirtual(output); output.fDiv(); output.invokeSpecial(ANY_NAME, "", "(F)V"); output.returnObject(); @@ -386,7 +418,7 @@ public class ZenTypeFloat extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASFLOAT); + METHOD_ASFLOAT.invokeVirtual(output); output.fRem(); output.invokeSpecial(ANY_NAME, "", "(F)V"); output.returnObject(); @@ -417,7 +449,7 @@ public class ZenTypeFloat extends ZenType { // return Float.compare(x, y) getValue(output); output.loadObject(1); - output.invoke(METHOD_ASFLOAT); + METHOD_ASFLOAT.invokeVirtual(output); output.invokeStatic(Float.class, "compare", int.class, float.class, float.class); output.returnInt(); } @@ -576,7 +608,7 @@ public class ZenTypeFloat extends ZenType { getValue(output); output.loadObject(1); - output.invoke(METHOD_ASFLOAT); + METHOD_ASFLOAT.invokeVirtual(output); output.fCmp(); output.ifICmpNE(lblNope); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeFloatObject.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeFloatObject.java index 2a8a303..fc62302 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeFloatObject.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeFloatObject.java @@ -6,23 +6,25 @@ package stanhebben.zenscript.type; -import org.objectweb.asm.Label; import org.objectweb.asm.Type; import stanhebben.zenscript.annotations.CompareType; import stanhebben.zenscript.annotations.OperatorType; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; -import stanhebben.zenscript.expression.ExpressionAs; import stanhebben.zenscript.expression.ExpressionNull; import stanhebben.zenscript.expression.partial.IPartialExpression; import static stanhebben.zenscript.type.ZenType.ANY; -import static stanhebben.zenscript.type.ZenType.BOOL; +import static stanhebben.zenscript.type.ZenType.BYTE; +import static stanhebben.zenscript.type.ZenType.BYTE_VALUE; import static stanhebben.zenscript.type.ZenType.STRING; -import stanhebben.zenscript.util.MethodOutput; +import stanhebben.zenscript.type.casting.CastingRuleNullableStaticMethod; +import stanhebben.zenscript.type.casting.CastingRuleNullableVirtualMethod; +import stanhebben.zenscript.type.casting.CastingRuleVirtualMethod; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; +import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.ZenPosition; import static stanhebben.zenscript.util.ZenTypeUtil.signature; -import stanhebben.zenscript.value.IAny; /** * @@ -74,6 +76,43 @@ public class ZenTypeFloatObject extends ZenType { } @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + rules.registerCastingRule(BYTE, new CastingRuleVirtualMethod(BYTE_VALUE)); + rules.registerCastingRule(BYTEOBJECT, new CastingRuleNullableStaticMethod( + BYTE_VALUEOF, + new CastingRuleVirtualMethod(BYTE_VALUE))); + rules.registerCastingRule(SHORT, new CastingRuleVirtualMethod(SHORT_VALUE)); + rules.registerCastingRule(SHORTOBJECT, new CastingRuleNullableStaticMethod( + SHORT_VALUEOF, + new CastingRuleVirtualMethod(SHORT_VALUE))); + rules.registerCastingRule(INT, new CastingRuleVirtualMethod(INT_VALUE)); + rules.registerCastingRule(INTOBJECT, new CastingRuleNullableStaticMethod( + INT_VALUEOF, + new CastingRuleVirtualMethod(INT_VALUE))); + rules.registerCastingRule(LONG, new CastingRuleVirtualMethod(LONG_VALUE)); + rules.registerCastingRule(LONGOBJECT, new CastingRuleNullableStaticMethod( + LONG_VALUEOF, + new CastingRuleVirtualMethod(LONG_VALUE))); + rules.registerCastingRule(FLOAT, new CastingRuleVirtualMethod(FLOAT_VALUE)); + rules.registerCastingRule(FLOATOBJECT, new CastingRuleNullableStaticMethod( + FLOAT_VALUEOF, + new CastingRuleVirtualMethod(FLOAT_VALUE))); + rules.registerCastingRule(DOUBLE, new CastingRuleVirtualMethod(DOUBLE_VALUE)); + rules.registerCastingRule(DOUBLEOBJECT, new CastingRuleNullableStaticMethod( + DOUBLE_VALUEOF, + new CastingRuleVirtualMethod(DOUBLE_VALUE))); + + rules.registerCastingRule(STRING, new CastingRuleNullableVirtualMethod(FLOATOBJECT, FLOAT_TOSTRING)); + rules.registerCastingRule(ANY, new CastingRuleNullableStaticMethod( + JavaMethod.getStatic(getAnyClassName(environment), "valueOf", ANY, FLOAT), + new CastingRuleVirtualMethod(FLOAT_VALUE))); + + if (followCasters) { + constructExpansionCastingRules(environment, rules); + } + } + + /*@Override public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { return FLOAT.canCastImplicit(type, environment); } @@ -92,7 +131,7 @@ public class ZenTypeFloatObject extends ZenType { } else { return new ExpressionAs(position, value, type); } - } + }*/ @Override public Class toJavaClass() { @@ -119,7 +158,7 @@ public class ZenTypeFloatObject extends ZenType { return true; } - @Override + /*@Override public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { if (type == this) { // nothing to do @@ -147,7 +186,7 @@ public class ZenTypeFloatObject extends ZenType { environment.getOutput().invokeVirtual(Float.class, "floatValue", float.class); FLOAT.compileCast(position, environment, type); } - } + }*/ @Override public String getName() { diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeFunction.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeFunction.java index de7e941..0af4649 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeFunction.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeFunction.java @@ -6,7 +6,11 @@ package stanhebben.zenscript.type; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.objectweb.asm.Type; import stanhebben.zenscript.annotations.CompareType; import stanhebben.zenscript.annotations.OperatorType; @@ -17,6 +21,9 @@ import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.ExpressionInvalid; import stanhebben.zenscript.expression.ExpressionNull; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.casting.CastingRuleMatchedFunction; +import stanhebben.zenscript.type.casting.ICastingRule; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; import stanhebben.zenscript.util.ZenPosition; /** @@ -27,6 +34,7 @@ public class ZenTypeFunction extends ZenType { private final ZenType returnType; private final ZenType[] argumentTypes; private final String name; + private final Map implementedInterfaces = new HashMap(); public ZenTypeFunction(ZenType returnType, List arguments) { this.returnType = returnType; @@ -85,20 +93,64 @@ public class ZenTypeFunction extends ZenType { public IZenIterator makeIterator(int numValues, IEnvironmentMethod methodOutput) { return null; } - + @Override - public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { - return equals(type) || canCastToNative(type) || canCastExpansion(environment, type); // TODO: LATER: expand - } - - @Override - public boolean canCastExplicit(ZenType type, IEnvironmentGlobal environment) { - return equals(type) || canCastToNative(type) || canCastExpansion(environment, type); // TODO: LATER: expand + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + if (followCasters) { + constructExpansionCastingRules(environment, rules); + } } @Override - public Expression cast(ZenPosition position, IEnvironmentGlobal environment, Expression value, ZenType type) { - throw new UnsupportedOperationException("not supported yet"); + public ICastingRule getCastingRule(ZenType type, IEnvironmentGlobal environment) { + if (implementedInterfaces.containsKey(type)) { + return implementedInterfaces.get(type); + } + + Class cls = type.toJavaClass(); + + System.out.println("Can cast this function to " + cls.getName() + "?"); + + if (cls.isInterface() && cls.getMethods().length == 1) { + // this is a functional interface + // do the method signatures match? + Method method = cls.getMethods()[0]; + ZenType methodReturnType = environment.getType(method.getGenericReturnType()); + ICastingRule returnCastingRule = null; + if (!returnType.equals(methodReturnType)) { + returnCastingRule = returnType.getCastingRule(environment.getType(method.getGenericReturnType()), environment); + if (returnCastingRule == null) { + System.out.println("Return types don't match"); + return null; + } + } + + java.lang.reflect.Type[] methodParameters = method.getGenericParameterTypes(); + if (methodParameters.length < argumentTypes.length) { + System.out.println("Argument count doesn't match"); + return null; + } + + ICastingRule[] argumentCastingRules = new ICastingRule[argumentTypes.length]; + for (int i = 0; i < argumentCastingRules.length; i++) { + ZenType argumentType = environment.getType(methodParameters[i]); + if (!argumentType.equals(argumentTypes[i])) { + argumentCastingRules[i] = argumentType.getCastingRule(argumentTypes[i], environment); + if (argumentCastingRules[i] == null) { + System.out.println("Argument " + i + " doesn't match"); + System.out.println("Cannot cast " + argumentType.getName() + " to " + argumentTypes[i].getName()); + return null; + } + } + } + + CastingRuleMatchedFunction castingRule = new CastingRuleMatchedFunction(this, type, returnCastingRule, argumentCastingRules); + implementedInterfaces.put(type, castingRule); + System.out.println("Can cast this function"); + return castingRule; + } + + return null; } @Override @@ -150,6 +202,11 @@ public class ZenTypeFunction extends ZenType { ZenPosition position, IEnvironmentGlobal environment, Expression receiver, Expression... arguments) { return null; // TODO: complete } + + @Override + public ZenType[] predictCallTypes(int numArguments) { + return Arrays.copyOf(argumentTypes, numArguments); + } @Override public Class toJavaClass() { @@ -157,13 +214,6 @@ public class ZenTypeFunction extends ZenType { return null; } - @Override - public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { - if (!compileCastExpansion(position, environment, type)) { - environment.error(position, "cannot cast " + this + " to " + type); - } - } - @Override public String getName() { return name; @@ -173,21 +223,4 @@ public class ZenTypeFunction extends ZenType { public Expression defaultValue(ZenPosition position) { return new ExpressionNull(position); } - - private boolean canCastToNative(ZenType type) { - if (!(type instanceof ZenTypeNative)) return false; - - //System.out.println("Check cast to native type " + type.getName()); - - ZenTypeNative ntype = (ZenTypeNative) type; - if (ntype.getNativeClass().isInterface() && ntype.getNativeClass().getMethods().length == 1) { - // ta-da! we got a functional interface - // does it match? - // TODO: expand - return true; // assume for now it is - } - - System.out.println("Cannot cast"); - return false; - } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeInt.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeInt.java index ca6ce51..3a6c200 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeInt.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeInt.java @@ -13,14 +13,23 @@ import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.ExpressionArithmeticBinary; import stanhebben.zenscript.expression.ExpressionArithmeticCompare; import stanhebben.zenscript.expression.ExpressionArithmeticUnary; -import stanhebben.zenscript.expression.ExpressionAs; import stanhebben.zenscript.expression.ExpressionInt; import stanhebben.zenscript.expression.ExpressionInvalid; import stanhebben.zenscript.expression.partial.IPartialExpression; import static stanhebben.zenscript.type.ZenType.BYTE; +import static stanhebben.zenscript.type.ZenType.BYTEOBJECT; +import static stanhebben.zenscript.type.ZenType.BYTE_VALUEOF; import static stanhebben.zenscript.type.ZenType.STRING; +import stanhebben.zenscript.type.casting.CastingRuleI2B; +import stanhebben.zenscript.type.casting.CastingRuleI2D; +import stanhebben.zenscript.type.casting.CastingRuleI2F; +import stanhebben.zenscript.type.casting.CastingRuleI2L; +import stanhebben.zenscript.type.casting.CastingRuleI2S; +import stanhebben.zenscript.type.casting.CastingRuleNone; +import stanhebben.zenscript.type.casting.CastingRuleStaticMethod; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; +import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.AnyClassWriter; -import static stanhebben.zenscript.util.AnyClassWriter.METHOD_ASBYTE; import static stanhebben.zenscript.util.AnyClassWriter.METHOD_ASINT; import static stanhebben.zenscript.util.AnyClassWriter.METHOD_ASSTRING; import static stanhebben.zenscript.util.AnyClassWriter.throwCastException; @@ -45,8 +54,30 @@ public class ZenTypeInt extends ZenType { public IZenIterator makeIterator(int numValues, IEnvironmentMethod methodOutput) { return null; } - + @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + rules.registerCastingRule(BYTE, new CastingRuleI2B(null)); + rules.registerCastingRule(BYTEOBJECT, new CastingRuleStaticMethod(BYTE_VALUEOF)); + rules.registerCastingRule(SHORT, new CastingRuleI2S(null)); + rules.registerCastingRule(SHORTOBJECT, new CastingRuleStaticMethod(SHORT_VALUEOF)); + rules.registerCastingRule(INTOBJECT, new CastingRuleStaticMethod(INT_VALUEOF)); + rules.registerCastingRule(LONG, new CastingRuleI2L(null)); + rules.registerCastingRule(LONGOBJECT, new CastingRuleStaticMethod(LONG_VALUEOF, new CastingRuleI2L(null))); + rules.registerCastingRule(FLOAT, new CastingRuleI2F(null)); + rules.registerCastingRule(FLOATOBJECT, new CastingRuleStaticMethod(FLOAT_VALUEOF, new CastingRuleI2F(null))); + rules.registerCastingRule(DOUBLE, new CastingRuleI2D(null)); + rules.registerCastingRule(DOUBLEOBJECT, new CastingRuleStaticMethod(DOUBLE_VALUEOF, new CastingRuleI2D(null))); + + rules.registerCastingRule(STRING, new CastingRuleStaticMethod(INT_TOSTRING_STATIC)); + rules.registerCastingRule(ANY, new CastingRuleStaticMethod(JavaMethod.getStatic(getAnyClassName(environment), "valueOf", ANY, INT))); + + if (followCasters) { + constructExpansionCastingRules(environment, rules); + } + } + + /*@Override public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { return (type.getNumberType() != 0 && type.getNumberType() >= NUM_INT) || type == ZenTypeString.INSTANCE @@ -71,7 +102,7 @@ public class ZenTypeInt extends ZenType { } else { return new ExpressionAs(position, value, type); } - } + }*/ @Override public Type toASMType() { @@ -109,7 +140,7 @@ public class ZenTypeInt extends ZenType { return false; } - @Override + /*@Override public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { MethodOutput output = environment.getOutput(); @@ -149,7 +180,7 @@ public class ZenTypeInt extends ZenType { } else if (!compileCastExpansion(position, environment, type)) { environment.error(position, "cannot cast " + this + " to " + type); } - } + }*/ @Override public Expression unary(ZenPosition position, IEnvironmentGlobal environment, Expression value, OperatorType operator) { @@ -320,7 +351,7 @@ public class ZenTypeInt extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASINT); + METHOD_ASINT.invokeVirtual(output); output.iAdd(); output.invokeSpecial(ANY_NAME, "", "(I)V"); output.returnObject(); @@ -332,7 +363,7 @@ public class ZenTypeInt extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASINT); + METHOD_ASINT.invokeVirtual(output); output.iSub(); output.invokeSpecial(ANY_NAME, "", "(I)V"); output.returnObject(); @@ -350,7 +381,7 @@ public class ZenTypeInt extends ZenType { getValue(output); output.invokeVirtual(StringBuilder.class, "append", StringBuilder.class, int.class); output.loadObject(1); - output.invoke(METHOD_ASSTRING); + METHOD_ASSTRING.invokeVirtual(output); output.invokeVirtual(StringBuilder.class, "append", StringBuilder.class, String.class); output.invokeVirtual(StringBuilder.class, "toString", String.class); output.invokeStatic(STRING.getAnyClassName(environment), "valueOf", "(Ljava/lang/String;)" + signature(IAny.class)); @@ -363,7 +394,7 @@ public class ZenTypeInt extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASINT); + METHOD_ASINT.invokeVirtual(output); output.iMul(); output.invokeSpecial(ANY_NAME, "", "(I)V"); output.returnObject(); @@ -375,7 +406,7 @@ public class ZenTypeInt extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASINT); + METHOD_ASINT.invokeVirtual(output); output.iDiv(); output.invokeSpecial(ANY_NAME, "", "(I)V"); output.returnObject(); @@ -387,7 +418,7 @@ public class ZenTypeInt extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASBYTE); + METHOD_ASINT.invokeVirtual(output); output.iRem(); output.invokeSpecial(ANY_NAME, "", "(I)V"); output.returnObject(); @@ -399,7 +430,7 @@ public class ZenTypeInt extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASINT); + METHOD_ASINT.invokeVirtual(output); output.iAnd(); output.invokeSpecial(ANY_NAME, "", "(I)V"); output.returnObject(); @@ -411,7 +442,7 @@ public class ZenTypeInt extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASINT); + METHOD_ASINT.invokeVirtual(output); output.iOr(); output.invokeSpecial(ANY_NAME, "", "(I)V"); output.returnObject(); @@ -423,7 +454,7 @@ public class ZenTypeInt extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASINT); + METHOD_ASINT.invokeVirtual(output); output.iXor(); output.invokeSpecial(ANY_NAME, "", "(I)V"); output.returnObject(); @@ -440,7 +471,7 @@ public class ZenTypeInt extends ZenType { public void defineCompareTo(MethodOutput output) { getValue(output); output.loadObject(1); - output.invoke(METHOD_ASINT); + METHOD_ASINT.invokeVirtual(output); output.iSub(); output.returnInt(); } @@ -597,7 +628,7 @@ public class ZenTypeInt extends ZenType { getValue(output); output.loadObject(1); - output.invoke(METHOD_ASINT); + METHOD_ASINT.invokeVirtual(output); output.ifICmpNE(lblNope); output.iConst1(); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeIntObject.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeIntObject.java index 1b2b781..6c2d1da 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeIntObject.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeIntObject.java @@ -6,23 +6,25 @@ package stanhebben.zenscript.type; -import org.objectweb.asm.Label; import org.objectweb.asm.Type; import stanhebben.zenscript.annotations.CompareType; import stanhebben.zenscript.annotations.OperatorType; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; -import stanhebben.zenscript.expression.ExpressionAs; import stanhebben.zenscript.expression.ExpressionNull; import stanhebben.zenscript.expression.partial.IPartialExpression; import static stanhebben.zenscript.type.ZenType.ANY; -import static stanhebben.zenscript.type.ZenType.BOOL; +import static stanhebben.zenscript.type.ZenType.BYTE; +import static stanhebben.zenscript.type.ZenType.BYTE_VALUE; import static stanhebben.zenscript.type.ZenType.STRING; -import stanhebben.zenscript.util.MethodOutput; +import stanhebben.zenscript.type.casting.CastingRuleNullableStaticMethod; +import stanhebben.zenscript.type.casting.CastingRuleNullableVirtualMethod; +import stanhebben.zenscript.type.casting.CastingRuleVirtualMethod; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; +import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.ZenPosition; import static stanhebben.zenscript.util.ZenTypeUtil.signature; -import stanhebben.zenscript.value.IAny; /** * @@ -74,6 +76,43 @@ public class ZenTypeIntObject extends ZenType { } @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + rules.registerCastingRule(BYTE, new CastingRuleVirtualMethod(BYTE_VALUE)); + rules.registerCastingRule(BYTEOBJECT, new CastingRuleNullableStaticMethod( + BYTE_VALUEOF, + new CastingRuleVirtualMethod(BYTE_VALUE))); + rules.registerCastingRule(SHORT, new CastingRuleVirtualMethod(SHORT_VALUE)); + rules.registerCastingRule(SHORTOBJECT, new CastingRuleNullableStaticMethod( + SHORT_VALUEOF, + new CastingRuleVirtualMethod(SHORT_VALUE))); + rules.registerCastingRule(INT, new CastingRuleVirtualMethod(INT_VALUE)); + rules.registerCastingRule(INTOBJECT, new CastingRuleNullableStaticMethod( + INT_VALUEOF, + new CastingRuleVirtualMethod(INT_VALUE))); + rules.registerCastingRule(LONG, new CastingRuleVirtualMethod(LONG_VALUE)); + rules.registerCastingRule(LONGOBJECT, new CastingRuleNullableStaticMethod( + LONG_VALUEOF, + new CastingRuleVirtualMethod(LONG_VALUE))); + rules.registerCastingRule(FLOAT, new CastingRuleVirtualMethod(FLOAT_VALUE)); + rules.registerCastingRule(FLOATOBJECT, new CastingRuleNullableStaticMethod( + FLOAT_VALUEOF, + new CastingRuleVirtualMethod(FLOAT_VALUE))); + rules.registerCastingRule(DOUBLE, new CastingRuleVirtualMethod(DOUBLE_VALUE)); + rules.registerCastingRule(DOUBLEOBJECT, new CastingRuleNullableStaticMethod( + DOUBLE_VALUEOF, + new CastingRuleVirtualMethod(DOUBLE_VALUE))); + + rules.registerCastingRule(STRING, new CastingRuleNullableVirtualMethod(INTOBJECT, INT_TOSTRING)); + rules.registerCastingRule(ANY, new CastingRuleNullableStaticMethod( + JavaMethod.getStatic(getAnyClassName(environment), "valueOf", ANY, INT), + new CastingRuleVirtualMethod(DOUBLE_VALUE))); + + if (followCasters) { + constructExpansionCastingRules(environment, rules); + } + } + + /*@Override public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { return INT.canCastImplicit(type, environment); } @@ -92,7 +131,7 @@ public class ZenTypeIntObject extends ZenType { } else { return new ExpressionAs(position, value, type); } - } + }*/ @Override public Class toJavaClass() { @@ -119,7 +158,7 @@ public class ZenTypeIntObject extends ZenType { return true; } - @Override + /*@Override public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { if (type == this) { // nothing to do @@ -147,7 +186,7 @@ public class ZenTypeIntObject extends ZenType { environment.getOutput().invokeVirtual(Integer.class, "intValue", int.class); INT.compileCast(position, environment, type); } - } + }*/ @Override public String getName() { diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeIntRange.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeIntRange.java index 320a877..4aac285 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeIntRange.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeIntRange.java @@ -16,9 +16,11 @@ import stanhebben.zenscript.compiler.ITypeRegistry; import stanhebben.zenscript.compiler.TypeRegistry; import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.ExpressionInvalid; -import stanhebben.zenscript.expression.ExpressionJavaCallVirtual; +import stanhebben.zenscript.expression.ExpressionCallVirtual; import stanhebben.zenscript.expression.ExpressionNull; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.MethodOutput; import stanhebben.zenscript.util.ZenPosition; @@ -32,8 +34,8 @@ import stanhebben.zenscript.value.IntRange; public class ZenTypeIntRange extends ZenType { public static final ZenTypeIntRange INSTANCE = new ZenTypeIntRange(); - private final JavaMethod methodFrom; - private final JavaMethod methodTo; + private final IJavaMethod methodFrom; + private final IJavaMethod methodTo; private ZenTypeIntRange() { ITypeRegistry dummy = new TypeRegistry(); @@ -73,9 +75,9 @@ public class ZenTypeIntRange extends ZenType { @Override public IPartialExpression getMember(ZenPosition position, IEnvironmentGlobal environment, IPartialExpression value, String name) { if (name.equals("from")) { - return new ExpressionJavaCallVirtual(position, methodFrom, value.eval(environment)); + return new ExpressionCallVirtual(position, environment, methodFrom, value.eval(environment)); } else if (name.equals("to")) { - return new ExpressionJavaCallVirtual(position, methodTo, value.eval(environment)); + return new ExpressionCallVirtual(position, environment, methodTo, value.eval(environment)); } else { environment.error(position, "no such member " + name + " in int range"); return new ExpressionInvalid(position); @@ -93,8 +95,13 @@ public class ZenTypeIntRange extends ZenType { environment.error(position, "int ranges cannot be called"); return new ExpressionInvalid(position); } - + @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + + } + + /*@Override public Expression cast(ZenPosition position, IEnvironmentGlobal environment, Expression value, ZenType type) { if (type == this) { return value; @@ -102,7 +109,7 @@ public class ZenTypeIntRange extends ZenType { environment.error(position, "cannot cast int ranges to any other type"); return new ExpressionInvalid(position); - } + }*/ @Override public IZenIterator makeIterator(int numValues, IEnvironmentMethod methodOutput) { @@ -113,7 +120,7 @@ public class ZenTypeIntRange extends ZenType { } } - @Override + /*@Override public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { return type == this; } @@ -121,7 +128,7 @@ public class ZenTypeIntRange extends ZenType { @Override public boolean canCastExplicit(ZenType type, IEnvironmentGlobal environment) { return type == this; - } + }*/ @Override public Class toJavaClass() { @@ -148,10 +155,10 @@ public class ZenTypeIntRange extends ZenType { return true; } - @Override + /*@Override public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } + }*/ @Override public String getName() { @@ -175,7 +182,7 @@ public class ZenTypeIntRange extends ZenType { MethodOutput output = method.getOutput(); output.dup(); // copy IntRange reference - output.invoke(methodFrom); + methodFrom.invokeVirtual(output); output.storeInt(locals[0]); } @@ -189,7 +196,7 @@ public class ZenTypeIntRange extends ZenType { MethodOutput output = method.getOutput(); output.dup(); // copy IntRange reference - output.invoke(methodTo); + methodTo.invokeVirtual(output); output.loadInt(locals[0]); output.iinc(locals[0]); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeLong.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeLong.java index 5a17833..67066a1 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeLong.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeLong.java @@ -13,13 +13,24 @@ import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.ExpressionArithmeticBinary; import stanhebben.zenscript.expression.ExpressionArithmeticCompare; import stanhebben.zenscript.expression.ExpressionArithmeticUnary; -import stanhebben.zenscript.expression.ExpressionAs; import stanhebben.zenscript.expression.ExpressionInt; import stanhebben.zenscript.expression.ExpressionInvalid; import stanhebben.zenscript.expression.partial.IPartialExpression; import static stanhebben.zenscript.type.ZenType.ANY; import static stanhebben.zenscript.type.ZenType.BYTE; +import static stanhebben.zenscript.type.ZenType.BYTEOBJECT; +import static stanhebben.zenscript.type.ZenType.BYTE_VALUEOF; import static stanhebben.zenscript.type.ZenType.STRING; +import stanhebben.zenscript.type.casting.CastingRuleI2B; +import stanhebben.zenscript.type.casting.CastingRuleI2D; +import stanhebben.zenscript.type.casting.CastingRuleI2F; +import stanhebben.zenscript.type.casting.CastingRuleI2L; +import stanhebben.zenscript.type.casting.CastingRuleI2S; +import stanhebben.zenscript.type.casting.CastingRuleL2F; +import stanhebben.zenscript.type.casting.CastingRuleL2I; +import stanhebben.zenscript.type.casting.CastingRuleStaticMethod; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; +import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.AnyClassWriter; import static stanhebben.zenscript.util.AnyClassWriter.METHOD_ASLONG; import static stanhebben.zenscript.util.AnyClassWriter.METHOD_ASSTRING; @@ -47,6 +58,28 @@ public class ZenTypeLong extends ZenType { } @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + rules.registerCastingRule(BYTE, new CastingRuleI2B(new CastingRuleL2I(null))); + rules.registerCastingRule(BYTEOBJECT, new CastingRuleStaticMethod(BYTE_VALUEOF, new CastingRuleI2B(new CastingRuleL2I(null)))); + rules.registerCastingRule(SHORT, new CastingRuleI2S(new CastingRuleL2I(null))); + rules.registerCastingRule(SHORTOBJECT, new CastingRuleStaticMethod(SHORT_VALUEOF, new CastingRuleI2S(new CastingRuleL2I(null)))); + rules.registerCastingRule(INT, new CastingRuleL2I(null)); + rules.registerCastingRule(INTOBJECT, new CastingRuleStaticMethod(INT_VALUEOF)); + rules.registerCastingRule(LONGOBJECT, new CastingRuleStaticMethod(LONG_VALUEOF, new CastingRuleI2L(null))); + rules.registerCastingRule(FLOAT, new CastingRuleL2F(null)); + rules.registerCastingRule(FLOATOBJECT, new CastingRuleStaticMethod(FLOAT_VALUEOF, new CastingRuleI2F(null))); + rules.registerCastingRule(DOUBLE, new CastingRuleI2D(null)); + rules.registerCastingRule(DOUBLEOBJECT, new CastingRuleStaticMethod(DOUBLE_VALUEOF, new CastingRuleI2D(null))); + + rules.registerCastingRule(STRING, new CastingRuleStaticMethod(LONG_TOSTRING_STATIC)); + rules.registerCastingRule(ANY, new CastingRuleStaticMethod(JavaMethod.getStatic(getAnyClassName(environment), "valueOf", ANY, LONG))); + + if (followCasters) { + constructExpansionCastingRules(environment, rules); + } + } + + /*@Override public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { return (type.getNumberType() != 0 && type.getNumberType() >= NUM_LONG) || type == ZenTypeString.INSTANCE @@ -71,7 +104,7 @@ public class ZenTypeLong extends ZenType { } else { return new ExpressionAs(position, value, type); } - } + }*/ @Override public Type toASMType() { @@ -109,7 +142,7 @@ public class ZenTypeLong extends ZenType { return false; } - @Override + /*@Override public void compileCast(stanhebben.zenscript.util.ZenPosition position, IEnvironmentMethod environment, ZenType type) { MethodOutput output = environment.getOutput(); @@ -153,7 +186,7 @@ public class ZenTypeLong extends ZenType { } else if (!compileCastExpansion(position, environment, type)) { environment.error(position, "cannot cast " + this + " to " + type); } - } + }*/ @Override public Expression unary(ZenPosition position, IEnvironmentGlobal environment, Expression value, OperatorType operator) { @@ -198,7 +231,7 @@ public class ZenTypeLong extends ZenType { @Override public String getName() { - return "name"; + return "long"; } @Override @@ -329,7 +362,7 @@ public class ZenTypeLong extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASLONG); + METHOD_ASLONG.invokeVirtual(output); output.lAdd(); output.invokeSpecial(ANY_NAME, "", "(J)V"); output.returnObject(); @@ -341,7 +374,7 @@ public class ZenTypeLong extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASLONG); + METHOD_ASLONG.invokeVirtual(output); output.lSub(); output.invokeSpecial(ANY_NAME, "", "(J)V"); output.returnObject(); @@ -359,7 +392,7 @@ public class ZenTypeLong extends ZenType { getValue(output); output.invokeVirtual(StringBuilder.class, "append", StringBuilder.class, long.class); output.loadObject(1); - output.invoke(METHOD_ASSTRING); + METHOD_ASSTRING.invokeVirtual(output); output.invokeVirtual(StringBuilder.class, "append", StringBuilder.class, String.class); output.invokeVirtual(StringBuilder.class, "toString", String.class); output.invokeStatic(STRING.getAnyClassName(environment), "valueOf", "(Ljava/lang/String;)" + signature(IAny.class)); @@ -372,7 +405,7 @@ public class ZenTypeLong extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASLONG); + METHOD_ASLONG.invokeVirtual(output); output.lMul(); output.invokeSpecial(ANY_NAME, "", "(J)V"); output.returnObject(); @@ -384,7 +417,7 @@ public class ZenTypeLong extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASLONG); + METHOD_ASLONG.invokeVirtual(output); output.lDiv(); output.invokeSpecial(ANY_NAME, "", "(J)V"); output.returnObject(); @@ -396,7 +429,7 @@ public class ZenTypeLong extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASLONG); + METHOD_ASLONG.invokeVirtual(output); output.lRem(); output.invokeSpecial(ANY_NAME, "", "(J)V"); output.returnObject(); @@ -408,7 +441,7 @@ public class ZenTypeLong extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASLONG); + METHOD_ASLONG.invokeVirtual(output); output.lAnd(); output.invokeSpecial(ANY_NAME, "", "(J)V"); output.returnObject(); @@ -420,7 +453,7 @@ public class ZenTypeLong extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASLONG); + METHOD_ASLONG.invokeVirtual(output); output.lOr(); output.invokeSpecial(ANY_NAME, "", "(J)V"); output.returnObject(); @@ -432,7 +465,7 @@ public class ZenTypeLong extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASLONG); + METHOD_ASLONG.invokeVirtual(output); output.lXor(); output.invokeSpecial(ANY_NAME, "", "(J)V"); output.returnObject(); @@ -450,7 +483,7 @@ public class ZenTypeLong extends ZenType { // return Long.compare(x, y) getValue(output); output.loadObject(1); - output.invoke(METHOD_ASLONG); + METHOD_ASLONG.invokeVirtual(output); output.invokeStatic(Long.class, "compare", int.class, long.class, long.class); output.returnInt(); } @@ -603,13 +636,13 @@ public class ZenTypeLong extends ZenType { public void defineEquals(MethodOutput output) { Label lblNope = new Label(); - output.loadObject(1); + output.loadObject(0); output.instanceOf(IAny.NAME); output.ifEQ(lblNope); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASLONG); + METHOD_ASLONG.invokeVirtual(output); output.lCmp(); output.ifICmpNE(lblNope); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeLongObject.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeLongObject.java index 5877e27..3367ac3 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeLongObject.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeLongObject.java @@ -6,23 +6,25 @@ package stanhebben.zenscript.type; -import org.objectweb.asm.Label; import org.objectweb.asm.Type; import stanhebben.zenscript.annotations.CompareType; import stanhebben.zenscript.annotations.OperatorType; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; -import stanhebben.zenscript.expression.ExpressionAs; import stanhebben.zenscript.expression.ExpressionNull; import stanhebben.zenscript.expression.partial.IPartialExpression; import static stanhebben.zenscript.type.ZenType.ANY; -import static stanhebben.zenscript.type.ZenType.BOOL; +import static stanhebben.zenscript.type.ZenType.BYTE; +import static stanhebben.zenscript.type.ZenType.BYTE_VALUE; import static stanhebben.zenscript.type.ZenType.STRING; -import stanhebben.zenscript.util.MethodOutput; +import stanhebben.zenscript.type.casting.CastingRuleNullableStaticMethod; +import stanhebben.zenscript.type.casting.CastingRuleNullableVirtualMethod; +import stanhebben.zenscript.type.casting.CastingRuleVirtualMethod; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; +import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.ZenPosition; import static stanhebben.zenscript.util.ZenTypeUtil.signature; -import stanhebben.zenscript.value.IAny; /** * @@ -74,6 +76,43 @@ public class ZenTypeLongObject extends ZenType { } @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + rules.registerCastingRule(BYTE, new CastingRuleVirtualMethod(BYTE_VALUE)); + rules.registerCastingRule(BYTEOBJECT, new CastingRuleNullableStaticMethod( + BYTE_VALUEOF, + new CastingRuleVirtualMethod(BYTE_VALUE))); + rules.registerCastingRule(SHORT, new CastingRuleVirtualMethod(SHORT_VALUE)); + rules.registerCastingRule(SHORTOBJECT, new CastingRuleNullableStaticMethod( + SHORT_VALUEOF, + new CastingRuleVirtualMethod(SHORT_VALUE))); + rules.registerCastingRule(INT, new CastingRuleVirtualMethod(INT_VALUE)); + rules.registerCastingRule(INTOBJECT, new CastingRuleNullableStaticMethod( + INT_VALUEOF, + new CastingRuleVirtualMethod(INT_VALUE))); + rules.registerCastingRule(LONG, new CastingRuleVirtualMethod(LONG_VALUE)); + rules.registerCastingRule(LONGOBJECT, new CastingRuleNullableStaticMethod( + LONG_VALUEOF, + new CastingRuleVirtualMethod(LONG_VALUE))); + rules.registerCastingRule(FLOAT, new CastingRuleVirtualMethod(FLOAT_VALUE)); + rules.registerCastingRule(FLOATOBJECT, new CastingRuleNullableStaticMethod( + FLOAT_VALUEOF, + new CastingRuleVirtualMethod(FLOAT_VALUE))); + rules.registerCastingRule(DOUBLE, new CastingRuleVirtualMethod(DOUBLE_VALUE)); + rules.registerCastingRule(DOUBLEOBJECT, new CastingRuleNullableStaticMethod( + DOUBLE_VALUEOF, + new CastingRuleVirtualMethod(DOUBLE_VALUE))); + + rules.registerCastingRule(STRING, new CastingRuleNullableVirtualMethod(LONGOBJECT, LONG_TOSTRING)); + rules.registerCastingRule(ANY, new CastingRuleNullableStaticMethod( + JavaMethod.getStatic(getAnyClassName(environment), "valueOf", ANY, LONG), + new CastingRuleVirtualMethod(LONG_VALUE))); + + if (followCasters) { + constructExpansionCastingRules(environment, rules); + } + } + + /*@Override public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { return LONG.canCastImplicit(type, environment); } @@ -92,7 +131,7 @@ public class ZenTypeLongObject extends ZenType { } else { return new ExpressionAs(position, value, type); } - } + }*/ @Override public Class toJavaClass() { @@ -119,7 +158,7 @@ public class ZenTypeLongObject extends ZenType { return true; } - @Override + /*@Override public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { if (type == this) { // nothing to do @@ -147,7 +186,7 @@ public class ZenTypeLongObject extends ZenType { environment.getOutput().invokeVirtual(Long.class, "longValue", long.class); LONG.compileCast(position, environment, type); } - } + }*/ @Override public String getName() { diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeNative.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeNative.java index bf5195f..eb74965 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeNative.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeNative.java @@ -15,12 +15,11 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Queue; -import org.objectweb.asm.ClassWriter; -import static org.objectweb.asm.ClassWriter.COMPUTE_FRAMES; +import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.Label; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; -import stanhebben.zenscript.ZenRuntimeException; +import stanhebben.zenscript.TypeExpansion; import stanhebben.zenscript.annotations.ZenCaster; import stanhebben.zenscript.annotations.CompareType; import stanhebben.zenscript.annotations.ZenClass; @@ -36,16 +35,18 @@ import stanhebben.zenscript.annotations.ZenSetter; import stanhebben.zenscript.annotations.ZenMethod; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; -import stanhebben.zenscript.compiler.EnvironmentMethod; import stanhebben.zenscript.compiler.ITypeRegistry; import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.ExpressionArithmeticUnary; -import stanhebben.zenscript.expression.ExpressionAs; +import stanhebben.zenscript.expression.ExpressionCallVirtual; import stanhebben.zenscript.expression.ExpressionCompareGeneric; import stanhebben.zenscript.expression.ExpressionInvalid; import stanhebben.zenscript.expression.ExpressionNull; import stanhebben.zenscript.expression.ExpressionString; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.casting.CastingRuleNone; +import stanhebben.zenscript.type.casting.CastingRuleNullableStaticMethod; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; import stanhebben.zenscript.type.iterator.IteratorIterable; import stanhebben.zenscript.type.iterator.IteratorList; import stanhebben.zenscript.type.iterator.IteratorMap; @@ -54,8 +55,13 @@ import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.type.natives.ZenNativeCaster; import stanhebben.zenscript.type.natives.ZenNativeMember; import stanhebben.zenscript.type.natives.ZenNativeOperator; +import stanhebben.zenscript.util.AnyClassWriter; +import static stanhebben.zenscript.util.AnyClassWriter.throwCastException; +import static stanhebben.zenscript.util.AnyClassWriter.throwUnsupportedException; +import stanhebben.zenscript.util.IAnyDefinition; import stanhebben.zenscript.util.MethodOutput; import stanhebben.zenscript.util.ZenPosition; +import static stanhebben.zenscript.util.ZenTypeUtil.internal; import static stanhebben.zenscript.util.ZenTypeUtil.signature; import stanhebben.zenscript.value.IAny; @@ -70,6 +76,8 @@ public class ZenTypeNative extends ZenType { private static final int ITERATOR_MAP = 3; private final Class cls; + private final String anyName; + private final String anyName2; private final List implementing; private final Map members; private final Map staticMembers; @@ -94,6 +102,9 @@ public class ZenTypeNative extends ZenType { binaryOperators = new ArrayList(); unaryOperators = new ArrayList(); implementing = new ArrayList(); + + anyName2 = cls.getName() + "Any"; + anyName = anyName2.replace('.', '/'); } public void complete(ITypeRegistry types) { @@ -149,8 +160,7 @@ public class ZenTypeNative extends ZenType { for (Annotation annotation : method.getAnnotations()) { if (annotation instanceof ZenCaster) { - Class output = method.getReturnType(); - casters.add(new ZenNativeCaster(cls, output, method.getName())); + casters.add(new ZenNativeCaster(JavaMethod.get(types, method))); isMethod = false; } else if (annotation instanceof ZenGetter) { ZenGetter getterAnnotation = (ZenGetter) annotation; @@ -159,7 +169,7 @@ public class ZenTypeNative extends ZenType { if (!members.containsKey(name)) { members.put(name, new ZenNativeMember()); } - members.get(name).setGetter(new JavaMethod(cls, method, types)); + members.get(name).setGetter(new JavaMethod(method, types)); isMethod = false; } else if (annotation instanceof ZenSetter) { ZenSetter setterAnnotation = (ZenSetter) annotation; @@ -168,12 +178,12 @@ public class ZenTypeNative extends ZenType { if (!members.containsKey(name)) { members.put(name, new ZenNativeMember()); } - members.get(name).setSetter(new JavaMethod(cls, method, types)); + members.get(name).setSetter(new JavaMethod(method, types)); isMethod = false; } else if (annotation instanceof ZenMemberGetter) { - binaryOperators.add(new ZenNativeOperator(OperatorType.MEMBERGETTER, new JavaMethod(cls, method, types))); + binaryOperators.add(new ZenNativeOperator(OperatorType.MEMBERGETTER, new JavaMethod(method, types))); } else if (annotation instanceof ZenMemberSetter) { - trinaryOperators.add(new ZenNativeOperator(OperatorType.MEMBERSETTER, new JavaMethod(cls, method, types))); + trinaryOperators.add(new ZenNativeOperator(OperatorType.MEMBERSETTER, new JavaMethod(method, types))); } else if (annotation instanceof ZenOperator) { ZenOperator operatorAnnotation = (ZenOperator) annotation; switch (operatorAnnotation.value()) { @@ -184,7 +194,7 @@ public class ZenTypeNative extends ZenType { } else { unaryOperators.add(new ZenNativeOperator( operatorAnnotation.value(), - new JavaMethod(cls, method, types))); + new JavaMethod(method, types))); } break; case ADD: @@ -205,7 +215,7 @@ public class ZenTypeNative extends ZenType { } else { binaryOperators.add(new ZenNativeOperator( operatorAnnotation.value(), - new JavaMethod(cls, method, types))); + new JavaMethod(method, types))); } break; case INDEXSET: @@ -214,7 +224,7 @@ public class ZenTypeNative extends ZenType { } else { trinaryOperators.add(new ZenNativeOperator( operatorAnnotation.value(), - new JavaMethod(cls, method, types))); + new JavaMethod(method, types))); } break; } @@ -234,12 +244,12 @@ public class ZenTypeNative extends ZenType { if (!staticMembers.containsKey(methodName)) { staticMembers.put(methodName, new ZenNativeMember()); } - staticMembers.get(methodName).addMethod(new JavaMethod(cls, method, types)); + staticMembers.get(methodName).addMethod(new JavaMethod(method, types)); } else { if (!members.containsKey(methodName)) { members.put(methodName, new ZenNativeMember()); } - members.get(methodName).addMethod(new JavaMethod(cls, method, types)); + members.get(methodName).addMethod(new JavaMethod(method, types)); } } } @@ -273,7 +283,12 @@ public class ZenTypeNative extends ZenType { @Override public String getAnyClassName(IEnvironmentGlobal global) { - return null; + if (!global.containsClass(anyName2)) { + global.putClass(anyName2, new byte[0]); + //global.putClass(anyName2, AnyClassWriter.construct(new AnyNativeDefinition(global), anyName2, toASMType())); + } + + return anyName; } @Override @@ -287,6 +302,7 @@ public class ZenTypeNative extends ZenType { } } } + if (member == null) { Expression evalue = value.eval(environment); IPartialExpression member2 = memberExpansion(position, environment, evalue, name); @@ -376,34 +392,48 @@ public class ZenTypeNative extends ZenType { } return null; } - + @Override - public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { - return type == this - || canCastImplicit(cls, type) - || canCastExpansion(environment, type); + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + if (cls.getSuperclass() != null) { + ZenType superType = environment.getType(cls.getSuperclass()); + + rules.registerCastingRule(superType, new CastingRuleNone(this, superType)); + + superType.constructCastingRules(environment, rules, followCasters); + } + + for (Class iface : cls.getInterfaces()) { + ZenType ifaceType = environment.getType(iface); + + rules.registerCastingRule(ifaceType, new CastingRuleNone(this, ifaceType)); + + ifaceType.constructCastingRules(environment, rules, followCasters); + } + + if (followCasters) { + for (ZenNativeCaster caster : casters) { + // TODO: implement + } + + TypeExpansion expansion = environment.getExpansion(getName()); + if (expansion != null) { + expansion.constructCastingRules(environment, rules); + } + } + + rules.registerCastingRule(ANY, new CastingRuleNullableStaticMethod(JavaMethod.getStatic( + getAnyClassName(environment), + "valueOf", + ANY, + this))); } @Override public boolean canCastExplicit(ZenType type, IEnvironmentGlobal environment) { return type == this - || canCastImplicit(cls, type) - || canCastImplicit(type, cls) - || canCastExpansion(environment, type); - } - - - @Override - public Expression cast(ZenPosition position, IEnvironmentGlobal environment, Expression value, ZenType type) { - if (type == this || canCastImplicit(cls, type)) { - return value; - } - - if (canCastExpansion(environment, type)) { - return castExpansion(position, environment, value, type); - } else { - return new ExpressionAs(position, value, type); - } + || canCastImplicit(type, environment) + || type.canCastExplicit(this, environment); } @Override @@ -431,400 +461,11 @@ public class ZenTypeNative extends ZenType { return true; } - /** - * Can we cast the given class to the given type implicitly? - * - * @param cls class to be casted - * @param type type to cast to - * @return true if casting is possible - */ - private static boolean canCastImplicit(Class cls, ZenType type) { - if (isEqual(cls, type)) return true; - if (type == BOOL) return true; - if (cls.getSuperclass() != null) { - if (canCastImplicit(cls.getSuperclass(), type)) return true; - } - for (Class iface : cls.getInterfaces()) { - if (canCastImplicit(iface, type)) return true; - } - return false; - } - - /** - * Can we cast the given type to the given class implicitly? - * - * @param type type to be casted - * @param cls type to cast to - * @return true if casting is possible - */ - private static boolean canCastImplicit(ZenType type, Class cls) { - if (isEqual(cls, type)) return true; - if (type == BOOL) return true; - if (type instanceof ZenTypeNative) { - Class clsFrom = ((ZenTypeNative) type).cls; - return cls.isAssignableFrom(clsFrom); - } - return false; - } - - private static boolean isEqual(Class cls, ZenType type) { - String signature = getSignature(cls); - return type.getSignature().equals(signature); - } - - private static String getSignature(Class cls) { - String signature = signature(cls); - if (Number.class.isAssignableFrom(cls)) { - if (cls == Byte.class) { - signature = "B"; - } else if (cls == Short.class) { - signature = "S"; - } else if (cls == Integer.class) { - signature = "I"; - } else if (cls == Long.class) { - signature = "J"; - } else if (cls == Float.class) { - signature = "F"; - } else if (cls == Double.class) { - signature = "D"; - } - } - return signature; - } - - @Override - public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType toType) { - if (toType == ZenTypeAny.INSTANCE) { - String anyClassName = this.cls.getName() + "__Any"; - String anySignature = signature(IAny.class); - String toSignature = "L" + anyClassName + ""; - - if (!environment.containsClass(anyClassName)) { - environment.putClass(anyClassName, new byte[0]); // prevent recursive issues - - ClassWriter newClass = new ClassWriter(COMPUTE_FRAMES); - newClass.visit( - Opcodes.V1_6, - Opcodes.ACC_PUBLIC, - anyClassName, - "L" + anyClassName + ";", - signature(Object.class), - new String[] { anySignature }); - - newClass.visitField(Opcodes.ACC_PRIVATE, "value", null, className, null); - - // static valueOf method - MethodOutput valueOfMethod = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, - "valueOf", - "(" + getSignature() + ")L" + anyClassName + ";", - null, - null); - valueOfMethod.start(); - valueOfMethod.newObject(anyClassName); - valueOfMethod.loadObject(0); - valueOfMethod.construct(anyClassName, getSignature()); - valueOfMethod.returnObject(); - valueOfMethod.end(); - - // single constructor - MethodOutput constructorMethod = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC, - "", - "(" + getSignature() + ")V", - null, - null); - constructorMethod.start(); - constructorMethod.loadObject(1); - constructorMethod.loadObject(0); - constructorMethod.putField(toSignature, "value", null); - constructorMethod.end(); - - // implementation for each of the interface methods - MethodOutput methodNot = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC, - "not", - "()" + anySignature, - null, - null); - methodNot.start(); - compileAnyUnary( - anySignature, - OperatorType.NOT, - new EnvironmentMethod(methodNot, environment)); - methodNot.end(); - - MethodOutput methodNeg = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC, - "neg", - "()" + anySignature, - null, - null); - methodNeg.start(); - compileAnyUnary( - anySignature, - OperatorType.NEG, - new EnvironmentMethod(methodNeg, environment)); - methodNeg.end(); - - MethodOutput methodAdd = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC, - "add", - "(" + signature(IAny.class) + ")" + anySignature, - null, - null); - methodAdd.start(); - compileAnyBinary( - anySignature, - OperatorType.ADD, - new EnvironmentMethod(methodAdd, environment)); - methodAdd.end(); - - MethodOutput methodSub = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC, - "sub", - "(" + signature(IAny.class) + ")" + anySignature, - null, - null); - methodSub.start(); - compileAnyBinary( - anySignature, - OperatorType.SUB, - new EnvironmentMethod(methodSub, environment)); - methodSub.end(); - - MethodOutput methodCat = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC, - "cat", - "(" + signature(IAny.class) + ")" + anySignature, - null, - null); - methodCat.start(); - compileAnyBinary( - anySignature, - OperatorType.CAT, - new EnvironmentMethod(methodCat, environment)); - methodCat.end(); - - MethodOutput methodMul = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC, - "mul", - "(" + signature(IAny.class) + ")" + anySignature, - null, - null); - methodMul.start(); - compileAnyBinary( - anySignature, - OperatorType.ADD, - new EnvironmentMethod(methodMul, environment)); - methodMul.end(); - - MethodOutput methodDiv = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC, - "div", - "(" + signature(IAny.class) + ")" + anySignature, - null, - null); - methodDiv.start(); - compileAnyBinary( - anySignature, - OperatorType.DIV, - new EnvironmentMethod(methodDiv, environment)); - methodDiv.end(); - - MethodOutput methodMod = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC, - "mod", - "(" + signature(IAny.class) + ")" + anySignature, - null, - null); - methodMod.start(); - compileAnyBinary( - anySignature, - OperatorType.MOD, - new EnvironmentMethod(methodMod, environment)); - methodMod.end(); - - MethodOutput methodAnd = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC, - "and", - "(" + signature(IAny.class) + ")" + anySignature, - null, - null); - methodAnd.start(); - compileAnyBinary( - anySignature, - OperatorType.AND, - new EnvironmentMethod(methodAnd, environment)); - methodAnd.end(); - - MethodOutput methodOr = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC, - "or", - "(" + signature(IAny.class) + ")" + anySignature, - null, - null); - methodOr.start(); - compileAnyBinary( - anySignature, - OperatorType.OR, - new EnvironmentMethod(methodOr, environment)); - methodOr.end(); - - MethodOutput methodXor = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC, - "xor", - "(" + signature(IAny.class) + ")" + anySignature, - null, - null); - methodXor.start(); - compileAnyBinary( - anySignature, - OperatorType.XOR, - new EnvironmentMethod(methodXor, environment)); - methodXor.end(); - - MethodOutput methodRange = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC, - "range", - "(" + signature(IAny.class) + ")" + anySignature, - null, - null); - methodRange.start(); - compileAnyBinary( - anySignature, - OperatorType.RANGE, - new EnvironmentMethod(methodRange, environment)); - methodRange.end(); - - MethodOutput methodContains = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC, - "contains", - "(" + signature(IAny.class) + ")" + anySignature, - null, - null); - methodContains.start(); - compileAnyBinary( - anySignature, - OperatorType.CONTAINS, - new EnvironmentMethod(methodContains, environment)); - methodContains.end(); - - MethodOutput methodIndexSet = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC, - "indexSet", - "(" + signature(IAny.class) + ")" + anySignature, - null, - null); - methodIndexSet.start(); - compileAnyBinary( - anySignature, - OperatorType.INDEXSET, - new EnvironmentMethod(methodIndexSet, environment)); - methodIndexSet.end(); - - MethodOutput methodCompare = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC, - "compareTo", - "(" + signature(IAny.class) + ")" + anySignature, - null, - null); - methodCompare.start(); - compileAnyBinary( - anySignature, - OperatorType.COMPARE, - new EnvironmentMethod(methodCompare, environment)); - methodCompare.end(); - - MethodOutput methodMember = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC, - "method", - "(" + signature(String.class) + ")" + anySignature, - null, - null); - methodMember.start(); - compileAnyMember(anySignature, new EnvironmentMethod(methodMember, environment)); - methodMember.end(); - - MethodOutput methodCall = new MethodOutput( - newClass, - Opcodes.ACC_PUBLIC, - "call", - "([" + signature(IAny.class) + ")" + anySignature, - null, - null); - methodCall.start(); - // TODO: complete - methodCall.aConstNull(); - methodCall.returnObject(); - methodCall.end(); - - // TODO: asXXX, iterators - - environment.putClass(anyClassName, newClass.toByteArray()); - } - return; - } else if (toType instanceof ZenTypeNative) { - Class toCls = toType.toJavaClass(); - if (toCls.isAssignableFrom(cls)) { - // nothing to do - return; - } - } - - MethodOutput output = environment.getOutput(); - if (toType == BOOL) { - Label lbl = new Label(); - output.iConst0(); - output.ifNull(lbl); - output.iConst1(); - output.label(lbl); - return; - } - for (ZenNativeCaster caster : casters) { - if (caster.getCasterClass() == toType.toJavaClass()) { - caster.compile(output); - return; - } - } - for (ZenNativeCaster caster : casters) { - if (toType.toJavaClass().isAssignableFrom(caster.getCasterClass())) { - caster.compile(output); - return; - } - } - if (compileCastExpansion(position, environment, toType)) { - return; - } - - output.checkCast(toType.toJavaClass()); - } - @Override public Expression unary(ZenPosition position, IEnvironmentGlobal environment, Expression value, OperatorType operator) { for (ZenNativeOperator unaryOperator : unaryOperators) { if (unaryOperator.getOperator() == operator) { - return unaryOperator - .getMethod() - .callVirtual(position, environment, value); + return new ExpressionCallVirtual(position, environment, unaryOperator.getMethod(), value); } } @@ -836,9 +477,7 @@ public class ZenTypeNative extends ZenType { public Expression binary(ZenPosition position, IEnvironmentGlobal environment, Expression left, Expression right, OperatorType operator) { for (ZenNativeOperator binaryOperator : binaryOperators) { if (binaryOperator.getOperator() == operator) { - return binaryOperator - .getMethod() - .callVirtual(position, environment, left, right); + return new ExpressionCallVirtual(position, environment, binaryOperator.getMethod(), left, right); } } @@ -850,9 +489,7 @@ public class ZenTypeNative extends ZenType { public Expression trinary(ZenPosition position, IEnvironmentGlobal environment, Expression first, Expression second, Expression third, OperatorType operator) { for (ZenNativeOperator trinaryOperator : trinaryOperators) { if (trinaryOperator.getOperator() == operator) { - return trinaryOperator - .getMethod() - .callVirtual(position, environment, first, second, third); + return new ExpressionCallVirtual(position, environment, trinaryOperator.getMethod(), first, second, third); } } @@ -865,9 +502,7 @@ public class ZenTypeNative extends ZenType { if (type == CompareType.EQ || type == CompareType.NE) { for (ZenNativeOperator binaryOperator : binaryOperators) { if (binaryOperator.getOperator() == OperatorType.EQUALS) { - Expression result = binaryOperator - .getMethod() - .callVirtual(position, environment, left, right); + Expression result = new ExpressionCallVirtual(position, environment, binaryOperator.getMethod(), left, right); if (type == CompareType.EQ) { return result; } else { @@ -883,9 +518,16 @@ public class ZenTypeNative extends ZenType { @Override public Expression call( ZenPosition position, IEnvironmentGlobal environment, Expression receiver, Expression... arguments) { + // TODO: support functional interfaces throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } + @Override + public ZenType[] predictCallTypes(int numArguments) { + // TODO: support functional interface + return new ZenType[numArguments]; + } + private boolean hasBinary(ZenType type, OperatorType operator) { for (ZenNativeOperator binaryOperator : binaryOperators) { if (binaryOperator.getOperator() == operator) { @@ -896,7 +538,7 @@ public class ZenTypeNative extends ZenType { return false; } - private void compileAnyUnary(String anySignature, OperatorType operator, IEnvironmentMethod environment) { + /*private void compileAnyUnary(String anySignature, OperatorType operator, IEnvironmentMethod environment) { List operators = new ArrayList(); for (ZenNativeOperator unary : this.unaryOperators) { if (unary.getOperator() == operator) { @@ -961,7 +603,7 @@ public class ZenTypeNative extends ZenType { MethodOutput output = environment.getOutput(); output.aConstNull(); output.returnObject(); - } + }*/ @Override public String getName() { @@ -992,4 +634,313 @@ public class ZenTypeNative extends ZenType { } } } + + private class AnyNativeDefinition implements IAnyDefinition { + private final IEnvironmentGlobal environment; + + public AnyNativeDefinition(IEnvironmentGlobal environment) { + this.environment = environment; + } + + @Override + public void defineMembers(ClassVisitor output) { + output.visitField(Opcodes.ACC_PRIVATE, "value", "F", null, null); + + MethodOutput valueOf = new MethodOutput(output, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "valueOf", "(F)" + signature(IAny.class), null, null); + valueOf.start(); + valueOf.newObject(anyName2); + valueOf.dup(); + valueOf.load(toASMType(), 0); + valueOf.construct(anyName2, "L" + cls.getName() + ";"); + valueOf.returnObject(); + valueOf.end(); + + MethodOutput constructor = new MethodOutput(output, Opcodes.ACC_PUBLIC, "", "(L" + cls.getName() + ";)V", null, null); + constructor.start(); + constructor.loadObject(0); + constructor.invokeSpecial(internal(Object.class), "", "()V"); + constructor.loadObject(0); + constructor.load(Type.FLOAT_TYPE, 1); + constructor.putField(anyName2, "value", "L" + cls.getName() + ";"); + constructor.returnType(Type.VOID_TYPE); + constructor.end(); + } + + @Override + public void defineStaticCanCastImplicit(MethodOutput output) { + // Class + // if (cls.isAssignableFrom(param)) return true; + output.constant(Type.getType(cls)); + output.loadObject(1); + output.invokeVirtual(Class.class, "isAssignableFrom", boolean.class, Class.class); + + Label lblNotAssignable = new Label(); + output.ifEQ(lblNotAssignable); + + output.iConst1(); + output.returnInt(); + + output.label(lblNotAssignable); + + for (ZenNativeCaster caster : casters) { + caster.compileAnyCanCastImplicit(ZenTypeNative.this, output, environment, 0); + } + + TypeExpansion expansion = environment.getExpansion(getName()); + if (expansion != null) { + expansion.compileAnyCanCastImplicit(ZenTypeNative.this, output, environment, 0); + } + + output.iConst0(); + output.returnInt(); + } + + @Override + public void defineStaticAs(MethodOutput output) { + output.constant(Type.getType(cls)); + output.loadObject(1); + output.invokeVirtual(Class.class, "isAssignableFrom", boolean.class, Class.class); + + Label lblNotAssignable = new Label(); + output.ifEQ(lblNotAssignable); + + output.loadObject(0); + output.returnObject(); + + output.label(lblNotAssignable); + + for (ZenNativeCaster caster : casters) { + caster.compileAnyCast(ZenTypeNative.this, output, environment, 0, 1); + } + + TypeExpansion expansion = environment.getExpansion(getName()); + if (expansion != null) { + expansion.compileAnyCast(ZenTypeNative.this, output, environment, 0, 1); + } + + throwCastException(output, "float", 1); + } + + @Override + public void defineNot(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "not"); + /*for (ZenNativeOperator unaryOperator : unaryOperators) { + if (unaryOperator.getOperator() == OperatorType.NOT) { + + } + } + + TypeExpansion expansion = environment.getExpansion(getName()); + if (expansion != null) { + if (expansion.compileAnyUnary(output, OperatorType.NOT)) { + + } + }*/ + } + + @Override + public void defineNeg(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "negate"); + } + + @Override + public void defineAdd(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "+"); + } + + @Override + public void defineSub(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "-"); + } + + @Override + public void defineCat(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "~"); + } + + @Override + public void defineMul(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "*"); + } + + @Override + public void defineDiv(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "/"); + } + + @Override + public void defineMod(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "%"); + } + + @Override + public void defineAnd(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "&"); + } + + @Override + public void defineOr(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "|"); + } + + @Override + public void defineXor(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "^"); + } + + @Override + public void defineRange(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), ".."); + } + + @Override + public void defineCompareTo(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "compare"); + } + + @Override + public void defineContains(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "in"); + } + + @Override + public void defineMemberGet(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "member get"); + } + + @Override + public void defineMemberSet(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "member set"); + } + + @Override + public void defineMemberCall(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "member call"); + } + + @Override + public void defineIndexGet(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "index get"); + } + + @Override + public void defineIndexSet(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "index set"); + } + + @Override + public void defineCall(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "call"); + } + + @Override + public void defineAsBool(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "asBool"); + } + + @Override + public void defineAsByte(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "asByte"); + } + + @Override + public void defineAsShort(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "asShort"); + } + + @Override + public void defineAsInt(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "asInt"); + } + + @Override + public void defineAsLong(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "asLong"); + } + + @Override + public void defineAsFloat(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "asFloat"); + } + + @Override + public void defineAsDouble(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "asDouble"); + } + + @Override + public void defineAsString(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "asString"); + } + + @Override + public void defineAs(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "as"); + } + + @Override + public void defineIs(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "is"); + } + + @Override + public void defineGetNumberType(MethodOutput output) { + output.iConst0(); + output.returnInt(); + } + + @Override + public void defineIteratorSingle(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "iterator"); + } + + @Override + public void defineIteratorMulti(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "iterator"); + } + + @Override + public void defineEquals(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "equals"); + } + + @Override + public void defineHashCode(MethodOutput output) { + // TODO: implement + throwUnsupportedException(output, getName(), "hashCode"); + } + } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeNull.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeNull.java index c13fc99..0dbacc6 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeNull.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeNull.java @@ -15,6 +15,9 @@ import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.ExpressionInvalid; import stanhebben.zenscript.expression.ExpressionNull; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.casting.CastingRuleNone; +import stanhebben.zenscript.type.casting.ICastingRule; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; import stanhebben.zenscript.util.ZenPosition; /** @@ -29,6 +32,20 @@ public class ZenTypeNull extends ZenType { } + @Override + public ICastingRule getCastingRule(ZenType type, IEnvironmentGlobal environment) { + if (type.isPointer()) { + return new CastingRuleNone(this, type); + } else { + return null; + } + } + + @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + + } + @Override public Expression unary(ZenPosition position, IEnvironmentGlobal environment, Expression value, OperatorType operator) { environment.error(position, "null has not operators"); @@ -77,20 +94,20 @@ public class ZenTypeNull extends ZenType { return null; } - @Override + /*@Override public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { return type.isPointer(); - } + }*/ @Override public boolean canCastExplicit(ZenType type, IEnvironmentGlobal environment) { return type.isPointer(); } - @Override + /*@Override public Expression cast(ZenPosition position, IEnvironmentGlobal environment, Expression value, ZenType type) { return value; - } + }*/ @Override public Class toJavaClass() { @@ -117,10 +134,10 @@ public class ZenTypeNull extends ZenType { return true; } - @Override + /*@Override public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { // nothing to do - } + }*/ @Override public String getName() { diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeShort.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeShort.java index 0cf613d..471bf34 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeShort.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeShort.java @@ -13,14 +13,22 @@ import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.ExpressionArithmeticBinary; import stanhebben.zenscript.expression.ExpressionArithmeticCompare; import stanhebben.zenscript.expression.ExpressionArithmeticUnary; -import stanhebben.zenscript.expression.ExpressionAs; import stanhebben.zenscript.expression.ExpressionInt; import stanhebben.zenscript.expression.ExpressionInvalid; import stanhebben.zenscript.expression.partial.IPartialExpression; import static stanhebben.zenscript.type.ZenType.BYTE; +import static stanhebben.zenscript.type.ZenType.BYTEOBJECT; +import static stanhebben.zenscript.type.ZenType.BYTE_VALUEOF; import static stanhebben.zenscript.type.ZenType.STRING; +import stanhebben.zenscript.type.casting.CastingRuleI2B; +import stanhebben.zenscript.type.casting.CastingRuleI2D; +import stanhebben.zenscript.type.casting.CastingRuleI2F; +import stanhebben.zenscript.type.casting.CastingRuleI2L; +import stanhebben.zenscript.type.casting.CastingRuleNone; +import stanhebben.zenscript.type.casting.CastingRuleStaticMethod; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; +import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.AnyClassWriter; -import static stanhebben.zenscript.util.AnyClassWriter.METHOD_ASBYTE; import static stanhebben.zenscript.util.AnyClassWriter.METHOD_ASSHORT; import static stanhebben.zenscript.util.AnyClassWriter.METHOD_ASSTRING; import static stanhebben.zenscript.util.AnyClassWriter.throwCastException; @@ -45,8 +53,28 @@ public class ZenTypeShort extends ZenType { public IZenIterator makeIterator(int numValues, IEnvironmentMethod environment) { return null; } - + @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + rules.registerCastingRule(BYTE, new CastingRuleI2B(null)); + rules.registerCastingRule(BYTEOBJECT, new CastingRuleStaticMethod(BYTE_VALUEOF)); + rules.registerCastingRule(SHORTOBJECT, new CastingRuleStaticMethod(SHORT_VALUEOF)); + rules.registerCastingRule(INT, new CastingRuleNone(SHORT, INT)); + rules.registerCastingRule(INTOBJECT, new CastingRuleStaticMethod(INT_VALUEOF)); + rules.registerCastingRule(LONG, new CastingRuleI2L(null)); + rules.registerCastingRule(LONGOBJECT, new CastingRuleStaticMethod(LONG_VALUEOF, new CastingRuleI2L(null))); + rules.registerCastingRule(FLOAT, new CastingRuleI2F(null)); + rules.registerCastingRule(FLOATOBJECT, new CastingRuleStaticMethod(FLOAT_VALUEOF, new CastingRuleI2F(null))); + rules.registerCastingRule(DOUBLE, new CastingRuleI2D(null)); + rules.registerCastingRule(DOUBLEOBJECT, new CastingRuleStaticMethod(DOUBLE_VALUEOF, new CastingRuleI2D(null))); + rules.registerCastingRule(ANY, new CastingRuleStaticMethod(JavaMethod.getStatic(getAnyClassName(environment), "valueOf", ANY, BYTE))); + + if (followCasters) { + constructExpansionCastingRules(environment, rules); + } + } + + /*@Override public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { return (type.getNumberType() != 0 && type.getNumberType() >= NUM_SHORT) || type == ZenTypeString.INSTANCE @@ -56,10 +84,7 @@ public class ZenTypeShort extends ZenType { @Override public boolean canCastExplicit(ZenType type, IEnvironmentGlobal environment) { - return type.getNumberType() != 0 - || type == ZenTypeString.INSTANCE - || type == ANY - || canCastExpansion(environment, type); + return canCastImplicit(type, environment); } @Override @@ -71,7 +96,7 @@ public class ZenTypeShort extends ZenType { } else { return new ExpressionAs(position, value, type); } - } + }*/ @Override public Type toASMType() { @@ -116,7 +141,7 @@ public class ZenTypeShort extends ZenType { return false; } - @Override + /*@Override public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { MethodOutput output = environment.getOutput(); @@ -155,7 +180,7 @@ public class ZenTypeShort extends ZenType { } else if (!compileCastExpansion(position, environment, type)) { environment.error(position, "cannot cast " + this + " to " + type); } - } + }*/ @Override public Expression unary(ZenPosition position, IEnvironmentGlobal environment, Expression value, OperatorType operator) { @@ -326,7 +351,7 @@ public class ZenTypeShort extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASSHORT); + METHOD_ASSHORT.invokeVirtual(output); output.iAdd(); output.invokeSpecial(ANY_NAME, "", "(S)V"); output.returnObject(); @@ -338,7 +363,7 @@ public class ZenTypeShort extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASSHORT); + METHOD_ASSHORT.invokeVirtual(output); output.iSub(); output.invokeSpecial(ANY_NAME, "", "(S)V"); output.returnObject(); @@ -356,7 +381,7 @@ public class ZenTypeShort extends ZenType { getValue(output); output.invokeVirtual(StringBuilder.class, "append", StringBuilder.class, int.class); output.loadObject(1); - output.invoke(METHOD_ASSTRING); + METHOD_ASSTRING.invokeVirtual(output); output.invokeVirtual(StringBuilder.class, "append", StringBuilder.class, String.class); output.invokeVirtual(StringBuilder.class, "toString", String.class); output.invokeStatic(STRING.getAnyClassName(environment), "valueOf", "(Ljava/lang/String;)" + signature(IAny.class)); @@ -369,7 +394,7 @@ public class ZenTypeShort extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASSHORT); + METHOD_ASSHORT.invokeVirtual(output); output.iMul(); output.invokeSpecial(ANY_NAME, "", "(S)V"); output.returnObject(); @@ -381,7 +406,7 @@ public class ZenTypeShort extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASSHORT); + METHOD_ASSHORT.invokeVirtual(output); output.iDiv(); output.invokeSpecial(ANY_NAME, "", "(S)V"); output.returnObject(); @@ -393,7 +418,7 @@ public class ZenTypeShort extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASSHORT); + METHOD_ASSHORT.invokeVirtual(output); output.iRem(); output.invokeSpecial(ANY_NAME, "", "(S)V"); output.returnObject(); @@ -405,7 +430,7 @@ public class ZenTypeShort extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASSHORT); + METHOD_ASSHORT.invokeVirtual(output); output.iAnd(); output.invokeSpecial(ANY_NAME, "", "(S)V"); output.returnObject(); @@ -417,7 +442,7 @@ public class ZenTypeShort extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASSHORT); + METHOD_ASSHORT.invokeVirtual(output); output.iOr(); output.invokeSpecial(ANY_NAME, "", "(S)V"); output.returnObject(); @@ -429,7 +454,7 @@ public class ZenTypeShort extends ZenType { output.dup(); getValue(output); output.loadObject(1); - output.invoke(METHOD_ASSHORT); + METHOD_ASSHORT.invokeVirtual(output); output.iXor(); output.invokeSpecial(ANY_NAME, "", "(S)V"); output.returnObject(); @@ -446,7 +471,7 @@ public class ZenTypeShort extends ZenType { public void defineCompareTo(MethodOutput output) { getValue(output); output.loadObject(1); - output.invoke(METHOD_ASBYTE); + METHOD_ASSHORT.invokeVirtual(output); output.iSub(); output.returnInt(); } @@ -602,7 +627,7 @@ public class ZenTypeShort extends ZenType { getValue(output); output.loadObject(1); - output.invoke(METHOD_ASSHORT); + METHOD_ASSHORT.invokeVirtual(output); output.ifICmpNE(lblNope); output.iConst1(); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeShortObject.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeShortObject.java index e96ba58..f8dc285 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeShortObject.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeShortObject.java @@ -6,23 +6,25 @@ package stanhebben.zenscript.type; -import org.objectweb.asm.Label; import org.objectweb.asm.Type; import stanhebben.zenscript.annotations.CompareType; import stanhebben.zenscript.annotations.OperatorType; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; -import stanhebben.zenscript.expression.ExpressionAs; import stanhebben.zenscript.expression.ExpressionNull; import stanhebben.zenscript.expression.partial.IPartialExpression; import static stanhebben.zenscript.type.ZenType.ANY; -import static stanhebben.zenscript.type.ZenType.BOOL; +import static stanhebben.zenscript.type.ZenType.BYTE; +import static stanhebben.zenscript.type.ZenType.BYTE_VALUE; import static stanhebben.zenscript.type.ZenType.STRING; -import stanhebben.zenscript.util.MethodOutput; +import stanhebben.zenscript.type.casting.CastingRuleNullableStaticMethod; +import stanhebben.zenscript.type.casting.CastingRuleNullableVirtualMethod; +import stanhebben.zenscript.type.casting.CastingRuleVirtualMethod; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; +import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.ZenPosition; import static stanhebben.zenscript.util.ZenTypeUtil.signature; -import stanhebben.zenscript.value.IAny; /** * @@ -74,6 +76,43 @@ public class ZenTypeShortObject extends ZenType { } @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + rules.registerCastingRule(BYTE, new CastingRuleVirtualMethod(BYTE_VALUE)); + rules.registerCastingRule(BYTEOBJECT, new CastingRuleNullableStaticMethod( + BYTE_VALUEOF, + new CastingRuleVirtualMethod(BYTE_VALUE))); + rules.registerCastingRule(SHORT, new CastingRuleVirtualMethod(SHORT_VALUE)); + rules.registerCastingRule(SHORTOBJECT, new CastingRuleNullableStaticMethod( + SHORT_VALUEOF, + new CastingRuleVirtualMethod(SHORT_VALUE))); + rules.registerCastingRule(INT, new CastingRuleVirtualMethod(INT_VALUE)); + rules.registerCastingRule(INTOBJECT, new CastingRuleNullableStaticMethod( + INT_VALUEOF, + new CastingRuleVirtualMethod(INT_VALUE))); + rules.registerCastingRule(LONG, new CastingRuleVirtualMethod(LONG_VALUE)); + rules.registerCastingRule(LONGOBJECT, new CastingRuleNullableStaticMethod( + LONG_VALUEOF, + new CastingRuleVirtualMethod(LONG_VALUE))); + rules.registerCastingRule(FLOAT, new CastingRuleVirtualMethod(FLOAT_VALUE)); + rules.registerCastingRule(FLOATOBJECT, new CastingRuleNullableStaticMethod( + FLOAT_VALUEOF, + new CastingRuleVirtualMethod(FLOAT_VALUE))); + rules.registerCastingRule(DOUBLE, new CastingRuleVirtualMethod(DOUBLE_VALUE)); + rules.registerCastingRule(DOUBLEOBJECT, new CastingRuleNullableStaticMethod( + DOUBLE_VALUEOF, + new CastingRuleVirtualMethod(DOUBLE_VALUE))); + + rules.registerCastingRule(STRING, new CastingRuleNullableVirtualMethod(SHORTOBJECT, SHORT_TOSTRING)); + rules.registerCastingRule(ANY, new CastingRuleNullableStaticMethod( + JavaMethod.getStatic(getAnyClassName(environment), "valueOf", ANY, SHORT), + new CastingRuleVirtualMethod(SHORT_VALUE))); + + if (followCasters) { + constructExpansionCastingRules(environment, rules); + } + } + + /*@Override public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { return SHORT.canCastImplicit(type, environment); } @@ -92,7 +131,7 @@ public class ZenTypeShortObject extends ZenType { } else { return new ExpressionAs(position, value, type); } - } + }*/ @Override public Class toJavaClass() { @@ -119,7 +158,7 @@ public class ZenTypeShortObject extends ZenType { return true; } - @Override + /*@Override public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { if (type == this) { // nothing to do @@ -147,7 +186,7 @@ public class ZenTypeShortObject extends ZenType { environment.getOutput().invokeVirtual(Short.class, "shortValue", short.class); SHORT.compileCast(position, environment, type); } - } + }*/ @Override public String getName() { diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeString.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeString.java index 6ab67f6..8597b21 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeString.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeString.java @@ -12,16 +12,19 @@ import stanhebben.zenscript.annotations.OperatorType; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; -import stanhebben.zenscript.expression.ExpressionAs; import stanhebben.zenscript.expression.ExpressionCompareGeneric; import stanhebben.zenscript.expression.ExpressionInvalid; -import stanhebben.zenscript.expression.ExpressionJavaCallVirtual; +import stanhebben.zenscript.expression.ExpressionCallVirtual; import stanhebben.zenscript.expression.ExpressionNull; import stanhebben.zenscript.expression.ExpressionStringConcat; import stanhebben.zenscript.expression.ExpressionStringContains; import stanhebben.zenscript.expression.ExpressionStringIndex; import stanhebben.zenscript.expression.partial.IPartialExpression; import static stanhebben.zenscript.type.ZenType.BYTE; +import stanhebben.zenscript.type.casting.CastingRuleNullableStaticMethod; +import stanhebben.zenscript.type.casting.CastingRuleStaticMethod; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; +import stanhebben.zenscript.type.natives.JavaMethod; import stanhebben.zenscript.util.AnyClassWriter; import static stanhebben.zenscript.util.AnyClassWriter.METHOD_ASINT; import static stanhebben.zenscript.util.AnyClassWriter.METHOD_ASSTRING; @@ -50,6 +53,34 @@ public class ZenTypeString extends ZenType { } @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + rules.registerCastingRule(BOOL, new CastingRuleStaticMethod(PARSE_BOOL)); + rules.registerCastingRule(BOOLOBJECT, new CastingRuleNullableStaticMethod(PARSE_BOOL_OBJECT)); + rules.registerCastingRule(BYTE, new CastingRuleStaticMethod(PARSE_BYTE)); + rules.registerCastingRule(BYTEOBJECT, new CastingRuleNullableStaticMethod(PARSE_BYTE_OBJECT)); + rules.registerCastingRule(SHORT, new CastingRuleStaticMethod(PARSE_SHORT)); + rules.registerCastingRule(SHORTOBJECT, new CastingRuleNullableStaticMethod(PARSE_SHORT_OBJECT)); + rules.registerCastingRule(INT, new CastingRuleStaticMethod(PARSE_INT)); + rules.registerCastingRule(INTOBJECT, new CastingRuleNullableStaticMethod(PARSE_INT_OBJECT)); + rules.registerCastingRule(LONG, new CastingRuleStaticMethod(PARSE_LONG)); + rules.registerCastingRule(LONGOBJECT, new CastingRuleNullableStaticMethod(PARSE_LONG_OBJECT)); + rules.registerCastingRule(FLOAT, new CastingRuleStaticMethod(PARSE_FLOAT)); + rules.registerCastingRule(FLOATOBJECT, new CastingRuleNullableStaticMethod(PARSE_FLOAT_OBJECT)); + rules.registerCastingRule(DOUBLE, new CastingRuleStaticMethod(PARSE_DOUBLE)); + rules.registerCastingRule(DOUBLEOBJECT, new CastingRuleNullableStaticMethod(PARSE_DOUBLE_OBJECT)); + rules.registerCastingRule(ANY, new CastingRuleNullableStaticMethod(JavaMethod.getStatic( + getAnyClassName(environment), + "valueOf", + ANY, + STRING + ))); + + if (followCasters) { + constructExpansionCastingRules(environment, rules); + } + } + + /*@Override public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { return type == this || type == ANY || canCastExpansion(environment, type); } @@ -70,7 +101,7 @@ public class ZenTypeString extends ZenType { } else { return new ExpressionAs(position, value, type); } - } + }*/ @Override public Type toASMType() { @@ -115,7 +146,7 @@ public class ZenTypeString extends ZenType { return true; } - @Override + /*@Override public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { MethodOutput output = environment.getOutput(); @@ -154,7 +185,7 @@ public class ZenTypeString extends ZenType { } else if (!compileCastExpansion(position, environment, type)) { environment.error(position, "cannot cast " + this + " to " + type); } - } + }*/ @Override public Expression unary( @@ -212,7 +243,7 @@ public class ZenTypeString extends ZenType { public Expression compare( ZenPosition position, IEnvironmentGlobal environment, Expression left, Expression right, CompareType type) { if (right.getType().canCastImplicit(STRING, environment)) { - return new ExpressionCompareGeneric(position, new ExpressionJavaCallVirtual(position, METHOD_ASINT, left, right), type); + return new ExpressionCompareGeneric(position, new ExpressionCallVirtual(position, environment, METHOD_ASINT, left, right), type); } Expression result = binaryExpansion(position, environment, left, right, OperatorType.COMPARE); @@ -241,6 +272,12 @@ public class ZenTypeString extends ZenType { return "string"; } + /** + * Returns the Java class name. + * + * @param environment + * @return + */ @Override public String getAnyClassName(IEnvironmentGlobal environment) { if (!environment.containsClass(ANY_NAME_2)) { @@ -345,7 +382,7 @@ public class ZenTypeString extends ZenType { getValue(output); output.invokeVirtual(StringBuilder.class, "append", StringBuilder.class, String.class); output.loadObject(1); - output.invoke(METHOD_ASSTRING); + METHOD_ASSTRING.invokeVirtual(output); output.invokeVirtual(StringBuilder.class, "append", StringBuilder.class, String.class); output.invokeVirtual(StringBuilder.class, "toString", String.class); output.invokeStatic(ANY_NAME, "valueOf", "(Ljava/lang/String;)" + signature(IAny.class)); @@ -391,7 +428,7 @@ public class ZenTypeString extends ZenType { public void defineCompareTo(MethodOutput output) { getValue(output); output.loadObject(1); - output.invoke(METHOD_ASSTRING); + METHOD_ASSTRING.invokeVirtual(output); output.invokeVirtual(String.class, "compareTo", int.class, String.class); output.returnInt(); } @@ -400,7 +437,7 @@ public class ZenTypeString extends ZenType { public void defineContains(MethodOutput output) { getValue(output); output.loadObject(1); - output.invoke(METHOD_ASSTRING); + METHOD_ASSTRING.invokeVirtual(output); output.invokeVirtual(String.class, "contains", boolean.class, CharSequence.class); output.returnInt(); } @@ -430,7 +467,7 @@ public class ZenTypeString extends ZenType { // return new AnyString(String.substring(other.asInt(), other.asInt() + 1)) getValue(output); output.loadObject(1); - output.invoke(METHOD_ASINT); + METHOD_ASINT.invokeVirtual(output); output.dup(); output.iConst1(); output.iAdd(); @@ -564,7 +601,7 @@ public class ZenTypeString extends ZenType { public void defineEquals(MethodOutput output) { getValue(output); output.loadObject(1); - output.invoke(METHOD_ASSTRING); + METHOD_ASSTRING.invokeVirtual(output); output.invokeVirtual(String.class, "equals", boolean.class, Object.class); output.returnInt(); } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeVoid.java b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeVoid.java index 7fdb6b5..042dbec 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeVoid.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/ZenTypeVoid.java @@ -14,6 +14,7 @@ import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.ExpressionInvalid; import stanhebben.zenscript.expression.partial.IPartialExpression; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; import stanhebben.zenscript.util.ZenPosition; /** @@ -50,6 +51,11 @@ public class ZenTypeVoid extends ZenType { } @Override + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules, boolean followCasters) { + + } + + /*@Override public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) { return type == this || canCastExpansion(environment, type); } @@ -63,7 +69,7 @@ public class ZenTypeVoid extends ZenType { public Expression cast(ZenPosition position, IEnvironmentGlobal environment, Expression value, ZenType type) { environment.error(position, "cannot cast void to other type"); return new ExpressionInvalid(position, type); - } + }*/ @Override public Type toASMType() { @@ -85,7 +91,7 @@ public class ZenTypeVoid extends ZenType { return false; } - @Override + /*@Override public void compileCast(ZenPosition position, IEnvironmentMethod environment, ZenType type) { if (type == this) { // nothing to do @@ -94,7 +100,7 @@ public class ZenTypeVoid extends ZenType { environment.error(position, "cannot cast " + this + " to " + type); } } - } + }*/ @Override public Expression unary( diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/BaseCastingRule.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/BaseCastingRule.java new file mode 100644 index 0000000..7d831bc --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/BaseCastingRule.java @@ -0,0 +1,39 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public abstract class BaseCastingRule implements ICastingRule { + private final ICastingRule baseRule; + + public BaseCastingRule(ICastingRule baseRule) { + this.baseRule = baseRule; + } + + @Override + public final void compile(IEnvironmentMethod method) { + if (baseRule != null) + baseRule.compile(method); + + compileInner(method); + } + + @Override + public final ZenType getInputType() { + return baseRule == null ? getInnerInputType() : baseRule.getInputType(); + } + + public abstract ZenType getInnerInputType(); + + public abstract void compileInner(IEnvironmentMethod method); +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyBool.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyBool.java new file mode 100644 index 0000000..28671e2 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyBool.java @@ -0,0 +1,36 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.value.IAny; + +/** + * + * @author Stan + */ +public class CastingAnyBool implements ICastingRule { + public static final CastingAnyBool INSTANCE = new CastingAnyBool(); + + private CastingAnyBool() {} + + @Override + public void compile(IEnvironmentMethod method) { + method.getOutput().invokeInterface(IAny.class, "asBool", boolean.class); + } + + @Override + public ZenType getInputType() { + return ZenType.ANY; + } + + @Override + public ZenType getResultingType() { + return ZenType.BOOL; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyByte.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyByte.java new file mode 100644 index 0000000..b3a6393 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyByte.java @@ -0,0 +1,36 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.value.IAny; + +/** + * + * @author Stan + */ +public class CastingAnyByte implements ICastingRule { + public static final CastingAnyByte INSTANCE = new CastingAnyByte(); + + private CastingAnyByte() {} + + @Override + public void compile(IEnvironmentMethod method) { + method.getOutput().invokeInterface(IAny.class, "asByte", byte.class); + } + + @Override + public ZenType getInputType() { + return ZenType.ANY; + } + + @Override + public ZenType getResultingType() { + return ZenType.BYTE; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyDouble.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyDouble.java new file mode 100644 index 0000000..0b76975 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyDouble.java @@ -0,0 +1,36 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.value.IAny; + +/** + * + * @author Stan + */ +public class CastingAnyDouble implements ICastingRule { + public static final CastingAnyDouble INSTANCE = new CastingAnyDouble(); + + private CastingAnyDouble() {} + + @Override + public void compile(IEnvironmentMethod method) { + method.getOutput().invokeInterface(IAny.class, "asDouble", double.class); + } + + @Override + public ZenType getInputType() { + return ZenType.ANY; + } + + @Override + public ZenType getResultingType() { + return ZenType.DOUBLE; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyFloat.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyFloat.java new file mode 100644 index 0000000..3ad4d51 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyFloat.java @@ -0,0 +1,36 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.value.IAny; + +/** + * + * @author Stan + */ +public class CastingAnyFloat implements ICastingRule { + public static final CastingAnyFloat INSTANCE = new CastingAnyFloat(); + + private CastingAnyFloat() {} + + @Override + public void compile(IEnvironmentMethod method) { + method.getOutput().invokeInterface(IAny.class, "asFloat", float.class); + } + + @Override + public ZenType getInputType() { + return ZenType.ANY; + } + + @Override + public ZenType getResultingType() { + return ZenType.FLOAT; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyInt.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyInt.java new file mode 100644 index 0000000..ec20e74 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyInt.java @@ -0,0 +1,36 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.value.IAny; + +/** + * + * @author Stan + */ +public class CastingAnyInt implements ICastingRule { + public static final CastingAnyInt INSTANCE = new CastingAnyInt(); + + private CastingAnyInt() {} + + @Override + public void compile(IEnvironmentMethod method) { + method.getOutput().invokeInterface(IAny.class, "asInt", int.class); + } + + @Override + public ZenType getInputType() { + return ZenType.ANY; + } + + @Override + public ZenType getResultingType() { + return ZenType.INT; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyLong.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyLong.java new file mode 100644 index 0000000..c386f6c --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyLong.java @@ -0,0 +1,36 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.value.IAny; + +/** + * + * @author Stan + */ +public class CastingAnyLong implements ICastingRule { + public static final CastingAnyLong INSTANCE = new CastingAnyLong(); + + private CastingAnyLong() {} + + @Override + public void compile(IEnvironmentMethod method) { + method.getOutput().invokeInterface(IAny.class, "asLong", long.class); + } + + @Override + public ZenType getInputType() { + return ZenType.ANY; + } + + @Override + public ZenType getResultingType() { + return ZenType.LONG; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyShort.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyShort.java new file mode 100644 index 0000000..c1d2c1f --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyShort.java @@ -0,0 +1,36 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.value.IAny; + +/** + * + * @author Stan + */ +public class CastingAnyShort implements ICastingRule { + public static final CastingAnyShort INSTANCE = new CastingAnyShort(); + + private CastingAnyShort() {} + + @Override + public void compile(IEnvironmentMethod method) { + method.getOutput().invokeInterface(IAny.class, "asShort", short.class); + } + + @Override + public ZenType getInputType() { + return ZenType.ANY; + } + + @Override + public ZenType getResultingType() { + return ZenType.SHORT; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyString.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyString.java new file mode 100644 index 0000000..8c22305 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingAnyString.java @@ -0,0 +1,51 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import org.objectweb.asm.Label; +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.util.MethodOutput; +import stanhebben.zenscript.value.IAny; + +/** + * + * @author Stan + */ +public class CastingAnyString implements ICastingRule { + public static final CastingAnyString INSTANCE = new CastingAnyString(); + + private CastingAnyString() {} + + @Override + public void compile(IEnvironmentMethod method) { + MethodOutput output = method.getOutput(); + Label lblNonNull = new Label(); + Label lblAfter = new Label(); + + output.dup(); + output.ifNonNull(lblNonNull); + output.pop(); + output.aConstNull(); + output.goTo(lblAfter); + + output.label(lblNonNull); + output.invokeInterface(IAny.class, "asString", String.class); + + output.label(lblAfter); + } + + @Override + public ZenType getInputType() { + return ZenType.ANY; + } + + @Override + public ZenType getResultingType() { + return ZenType.STRING; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleAny.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleAny.java new file mode 100644 index 0000000..a1c3fc1 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleAny.java @@ -0,0 +1,39 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.value.IAny; + +/** + * + * @author Stan + */ +public class CastingRuleAny implements ICastingRule { + private final ZenType toType; + + public CastingRuleAny(ZenType toType) { + this.toType = toType; + } + + @Override + public void compile(IEnvironmentMethod method) { + method.getOutput().constant(toType); + method.getOutput().invokeInterface(IAny.class, "as", Class.class, Object.class); + } + + @Override + public ZenType getInputType() { + return ZenType.ANY; + } + + @Override + public ZenType getResultingType() { + return toType; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleAnyAs.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleAnyAs.java new file mode 100644 index 0000000..f2c08ec --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleAnyAs.java @@ -0,0 +1,40 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import org.objectweb.asm.Type; +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.value.IAny; + +/** + * + * @author Stan + */ +public class CastingRuleAnyAs implements ICastingRule { + private final ZenType type; + + public CastingRuleAnyAs(ZenType type) { + this.type = type; + } + + @Override + public void compile(IEnvironmentMethod method) { + method.getOutput().constant(Type.getType(type.toJavaClass())); + method.getOutput().invokeInterface(IAny.class, "as", Class.class, Object.class); + } + + @Override + public ZenType getInputType() { + return ZenType.ANY; + } + + @Override + public ZenType getResultingType() { + return type; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleArrayArray.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleArrayArray.java new file mode 100644 index 0000000..6e5671c --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleArrayArray.java @@ -0,0 +1,87 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import org.objectweb.asm.Label; +import org.objectweb.asm.Type; +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.ZenTypeArrayBasic; +import stanhebben.zenscript.util.MethodOutput; + +/** + * + * @author Stan + */ +public class CastingRuleArrayArray implements ICastingRule { + private final ICastingRule base; + private final ZenTypeArrayBasic from; + private final ZenTypeArrayBasic to; + + public CastingRuleArrayArray(ICastingRule base, ZenTypeArrayBasic from, ZenTypeArrayBasic to) { + this.base = base; + this.from = from; + this.to = to; + } + + @Override + public void compile(IEnvironmentMethod method) { + MethodOutput output = method.getOutput(); + + Type fromType = from.getBaseType().toASMType(); + Type toType = to.getBaseType().toASMType(); + + int result = output.local(to.toASMType()); + + output.dup(); + output.arrayLength(); + output.newArray(toType); + output.storeObject(result); + + output.iConst0(); + + Label lbl = new Label(); + output.label(lbl); + + // stack: original index + output.dupX1(); + output.dupX1(); + output.arrayLoad(fromType); + + // stack: original index value + if (base != null) + base.compile(method); + + output.loadObject(result); + output.dupX2(); + output.dupX2(); + output.arrayStore(toType); + output.pop(); + + // stack: original index + output.iConst1(); + output.iAdd(); + output.dupX1(); + output.arrayLength(); + output.ifICmpGE(lbl); + + output.pop(); + output.pop(); + + output.loadObject(result); + } + + @Override + public ZenType getInputType() { + return from; + } + + @Override + public ZenType getResultingType() { + return to; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleArrayList.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleArrayList.java new file mode 100644 index 0000000..6c94d95 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleArrayList.java @@ -0,0 +1,74 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.ZenTypeArrayBasic; +import stanhebben.zenscript.type.ZenTypeArrayList; +import stanhebben.zenscript.util.MethodOutput; + +/** + * + * @author Stan + */ +public class CastingRuleArrayList implements ICastingRule { + private final ICastingRule base; + private final ZenTypeArrayBasic from; + private final ZenTypeArrayList to; + + public CastingRuleArrayList(ICastingRule base, ZenTypeArrayBasic from, ZenTypeArrayList to) { + this.base = base; + this.from = from; + this.to = to; + } + + @Override + public void compile(IEnvironmentMethod method) { + MethodOutput output = method.getOutput(); + + // TODO: implement this + throw new UnsupportedOperationException("Not yet implemented"); + +/* Type fromType = componentFrom.toASMType(); + Type toType = componentTo.toASMType(); + + int result = output.local(List.class); + int iterator = output.local(Iterator.class); + + // construct new list + output.dup(); + + + output.invoke(List.class, "iterator", void.class); + output.storeObject(iterator); + + Label loop = new Label(); + output.label(loop); + output.loadObject(iterator); + + + if (base != null) + base.compile(method); + + + + output.pop(); + + output.loadObject(result);*/ + } + + @Override + public ZenType getInputType() { + return from; + } + + @Override + public ZenType getResultingType() { + return to; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleD2F.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleD2F.java new file mode 100644 index 0000000..15593ce --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleD2F.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public class CastingRuleD2F extends BaseCastingRule { + public CastingRuleD2F(ICastingRule baseRule) { + super(baseRule); + } + + @Override + public void compileInner(IEnvironmentMethod method) { + method.getOutput().d2f(); + } + + @Override + public ZenType getInnerInputType() { + return ZenType.DOUBLE; + } + + @Override + public ZenType getResultingType() { + return ZenType.FLOAT; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleD2I.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleD2I.java new file mode 100644 index 0000000..dc4988e --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleD2I.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public class CastingRuleD2I extends BaseCastingRule { + public CastingRuleD2I(ICastingRule baseRule) { + super(baseRule); + } + + @Override + public void compileInner(IEnvironmentMethod method) { + method.getOutput().d2i(); + } + + @Override + public ZenType getInnerInputType() { + return ZenType.DOUBLE; + } + + @Override + public ZenType getResultingType() { + return ZenType.INT; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleD2L.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleD2L.java new file mode 100644 index 0000000..5dc46c1 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleD2L.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public class CastingRuleD2L extends BaseCastingRule { + public CastingRuleD2L(ICastingRule baseRule) { + super(baseRule); + } + + @Override + public void compileInner(IEnvironmentMethod method) { + method.getOutput().d2l(); + } + + @Override + public ZenType getInnerInputType() { + return ZenType.DOUBLE; + } + + @Override + public ZenType getResultingType() { + return ZenType.LONG; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleDelegateArray.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleDelegateArray.java new file mode 100644 index 0000000..00e926e --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleDelegateArray.java @@ -0,0 +1,31 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.ZenTypeArrayBasic; +import stanhebben.zenscript.type.ZenTypeArrayList; + +/** + * + * @author Stan + */ +public class CastingRuleDelegateArray implements ICastingRuleDelegate { + private final ICastingRuleDelegate base; + private final ZenTypeArrayBasic from; + + public CastingRuleDelegateArray(ICastingRuleDelegate base, ZenTypeArrayBasic from) { + this.base = base; + this.from = from; + } + + @Override + public void registerCastingRule(ZenType type, ICastingRule rule) { + base.registerCastingRule(new ZenTypeArrayBasic(type), new CastingRuleArrayArray(rule, from, new ZenTypeArrayBasic(type))); + base.registerCastingRule(new ZenTypeArrayList(type), new CastingRuleArrayList(rule, from, new ZenTypeArrayList(type))); + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleDelegateList.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleDelegateList.java new file mode 100644 index 0000000..cc98413 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleDelegateList.java @@ -0,0 +1,31 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.ZenTypeArrayBasic; +import stanhebben.zenscript.type.ZenTypeArrayList; + +/** + * + * @author Stan + */ +public class CastingRuleDelegateList implements ICastingRuleDelegate { + private final ICastingRuleDelegate base; + private final ZenTypeArrayList from; + + public CastingRuleDelegateList(ICastingRuleDelegate base, ZenTypeArrayList from) { + this.base = base; + this.from = from; + } + + @Override + public void registerCastingRule(ZenType type, ICastingRule rule) { + base.registerCastingRule(new ZenTypeArrayBasic(type), new CastingRuleListArray(rule, from, new ZenTypeArrayBasic(type))); + base.registerCastingRule(new ZenTypeArrayList(type), new CastingRuleListList(rule, from, new ZenTypeArrayList(type))); + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleDelegateMap.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleDelegateMap.java new file mode 100644 index 0000000..6a63977 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleDelegateMap.java @@ -0,0 +1,27 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import java.util.Map; +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public class CastingRuleDelegateMap implements ICastingRuleDelegate { + private final Map target; + + public CastingRuleDelegateMap(Map target) { + this.target = target; + } + + @Override + public void registerCastingRule(ZenType type, ICastingRule rule) { + target.put(type, rule); + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleDelegateStaticMethod.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleDelegateStaticMethod.java new file mode 100644 index 0000000..c239675 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleDelegateStaticMethod.java @@ -0,0 +1,29 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.natives.IJavaMethod; + +/** + * + * @author Stan + */ +public class CastingRuleDelegateStaticMethod implements ICastingRuleDelegate { + private final ICastingRuleDelegate target; + private final IJavaMethod method; + + public CastingRuleDelegateStaticMethod(ICastingRuleDelegate target, IJavaMethod method) { + this.target = target; + this.method = method; + } + + @Override + public void registerCastingRule(ZenType type, ICastingRule rule) { + target.registerCastingRule(type, new CastingRuleStaticMethod(method, rule)); + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleF2D.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleF2D.java new file mode 100644 index 0000000..21aee06 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleF2D.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public class CastingRuleF2D extends BaseCastingRule { + public CastingRuleF2D(ICastingRule baseRule) { + super(baseRule); + } + + @Override + public void compileInner(IEnvironmentMethod method) { + method.getOutput().f2d(); + } + + @Override + public ZenType getInnerInputType() { + return ZenType.FLOAT; + } + + @Override + public ZenType getResultingType() { + return ZenType.DOUBLE; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleF2I.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleF2I.java new file mode 100644 index 0000000..af3dd3e --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleF2I.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public class CastingRuleF2I extends BaseCastingRule { + public CastingRuleF2I(ICastingRule baseRule) { + super(baseRule); + } + + @Override + public void compileInner(IEnvironmentMethod method) { + method.getOutput().f2i(); + } + + @Override + public ZenType getInnerInputType() { + return ZenType.FLOAT; + } + + @Override + public ZenType getResultingType() { + return ZenType.INT; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleF2L.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleF2L.java new file mode 100644 index 0000000..5f9ac37 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleF2L.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public class CastingRuleF2L extends BaseCastingRule { + public CastingRuleF2L(ICastingRule baseRule) { + super(baseRule); + } + + @Override + public void compileInner(IEnvironmentMethod method) { + method.getOutput().f2l(); + } + + @Override + public ZenType getInnerInputType() { + return ZenType.FLOAT; + } + + @Override + public ZenType getResultingType() { + return ZenType.LONG; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleI2B.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleI2B.java new file mode 100644 index 0000000..730ca62 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleI2B.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public class CastingRuleI2B extends BaseCastingRule { + public CastingRuleI2B(ICastingRule baseRule) { + super(baseRule); + } + + @Override + public void compileInner(IEnvironmentMethod method) { + method.getOutput().i2b(); + } + + @Override + public ZenType getInnerInputType() { + return ZenType.INT; + } + + @Override + public ZenType getResultingType() { + return ZenType.BYTE; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleI2D.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleI2D.java new file mode 100644 index 0000000..d960b13 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleI2D.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public class CastingRuleI2D extends BaseCastingRule { + public CastingRuleI2D(ICastingRule baseRule) { + super(baseRule); + } + + @Override + public void compileInner(IEnvironmentMethod method) { + method.getOutput().i2d(); + } + + @Override + public ZenType getInnerInputType() { + return ZenType.INT; + } + + @Override + public ZenType getResultingType() { + return ZenType.DOUBLE; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleI2F.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleI2F.java new file mode 100644 index 0000000..abf234b --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleI2F.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public class CastingRuleI2F extends BaseCastingRule { + public CastingRuleI2F(ICastingRule baseRule) { + super(baseRule); + } + + @Override + public void compileInner(IEnvironmentMethod method) { + method.getOutput().i2f(); + } + + @Override + public ZenType getInnerInputType() { + return ZenType.INT; + } + + @Override + public ZenType getResultingType() { + return ZenType.FLOAT; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleI2L.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleI2L.java new file mode 100644 index 0000000..83128be --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleI2L.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public class CastingRuleI2L extends BaseCastingRule { + public CastingRuleI2L(ICastingRule baseRule) { + super(baseRule); + } + + @Override + public void compileInner(IEnvironmentMethod method) { + method.getOutput().i2l(); + } + + @Override + public ZenType getInnerInputType() { + return ZenType.INT; + } + + @Override + public ZenType getResultingType() { + return ZenType.LONG; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleI2S.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleI2S.java new file mode 100644 index 0000000..374f13b --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleI2S.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public class CastingRuleI2S extends BaseCastingRule { + public CastingRuleI2S(ICastingRule baseRule) { + super(baseRule); + } + + @Override + public void compileInner(IEnvironmentMethod method) { + method.getOutput().i2s(); + } + + @Override + public ZenType getInnerInputType() { + return ZenType.INT; + } + + @Override + public ZenType getResultingType() { + return ZenType.SHORT; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleL2D.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleL2D.java new file mode 100644 index 0000000..1522b50 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleL2D.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public class CastingRuleL2D extends BaseCastingRule { + public CastingRuleL2D(ICastingRule baseRule) { + super(baseRule); + } + + @Override + public void compileInner(IEnvironmentMethod method) { + method.getOutput().l2d(); + } + + @Override + public ZenType getInnerInputType() { + return ZenType.LONG; + } + + @Override + public ZenType getResultingType() { + return ZenType.DOUBLE; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleL2F.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleL2F.java new file mode 100644 index 0000000..472091d --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleL2F.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public class CastingRuleL2F extends BaseCastingRule { + public CastingRuleL2F(ICastingRule baseRule) { + super(baseRule); + } + + @Override + public void compileInner(IEnvironmentMethod method) { + method.getOutput().l2f(); + } + + @Override + public ZenType getInnerInputType() { + return ZenType.LONG; + } + + @Override + public ZenType getResultingType() { + return ZenType.FLOAT; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleL2I.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleL2I.java new file mode 100644 index 0000000..84a1a7b --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleL2I.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public class CastingRuleL2I extends BaseCastingRule { + public CastingRuleL2I(ICastingRule baseRule) { + super(baseRule); + } + + @Override + public void compileInner(IEnvironmentMethod method) { + method.getOutput().l2i(); + } + + @Override + public ZenType getInnerInputType() { + return ZenType.LONG; + } + + @Override + public ZenType getResultingType() { + return ZenType.INT; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleListArray.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleListArray.java new file mode 100644 index 0000000..34084eb --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleListArray.java @@ -0,0 +1,74 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.ZenTypeArrayBasic; +import stanhebben.zenscript.type.ZenTypeArrayList; +import stanhebben.zenscript.util.MethodOutput; + +/** + * + * @author Stan + */ +public class CastingRuleListArray implements ICastingRule { + private final ICastingRule base; + private final ZenTypeArrayList from; + private final ZenTypeArrayBasic to; + + public CastingRuleListArray(ICastingRule base, ZenTypeArrayList from, ZenTypeArrayBasic to) { + this.base = base; + this.from = from; + this.to = to; + } + + @Override + public void compile(IEnvironmentMethod method) { + MethodOutput output = method.getOutput(); + + // TODO: implement this + throw new UnsupportedOperationException("Not yet implemented"); + +/* Type fromType = componentFrom.toASMType(); + Type toType = componentTo.toASMType(); + + int result = output.local(List.class); + int iterator = output.local(Iterator.class); + + // construct new list + output.dup(); + + + output.invoke(List.class, "iterator", void.class); + output.storeObject(iterator); + + Label loop = new Label(); + output.label(loop); + output.loadObject(iterator); + + + if (base != null) + base.compile(method); + + + + output.pop(); + + output.loadObject(result);*/ + } + + @Override + public ZenType getInputType() { + return from; + } + + @Override + public ZenType getResultingType() { + return to; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleListList.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleListList.java new file mode 100644 index 0000000..57074c8 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleListList.java @@ -0,0 +1,73 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.ZenTypeArrayList; +import stanhebben.zenscript.util.MethodOutput; + +/** + * + * @author Stan + */ +public class CastingRuleListList implements ICastingRule { + private final ICastingRule base; + private final ZenTypeArrayList from; + private final ZenTypeArrayList to; + + public CastingRuleListList(ICastingRule base, ZenTypeArrayList from, ZenTypeArrayList to) { + this.base = base; + this.from = from; + this.to = to; + } + + @Override + public void compile(IEnvironmentMethod method) { + MethodOutput output = method.getOutput(); + + // TODO: implement this + throw new UnsupportedOperationException("Not yet implemented"); + +/* Type fromType = componentFrom.toASMType(); + Type toType = componentTo.toASMType(); + + int result = output.local(List.class); + int iterator = output.local(Iterator.class); + + // construct new list + output.dup(); + + + output.invoke(List.class, "iterator", void.class); + output.storeObject(iterator); + + Label loop = new Label(); + output.label(loop); + output.loadObject(iterator); + + + if (base != null) + base.compile(method); + + + + output.pop(); + + output.loadObject(result);*/ + } + + @Override + public ZenType getInputType() { + return from; + } + + @Override + public ZenType getResultingType() { + return to; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleMap.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleMap.java new file mode 100644 index 0000000..70f9f54 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleMap.java @@ -0,0 +1,45 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.ZenTypeAssociative; + +/** + * + * @author Stan + */ +public class CastingRuleMap implements ICastingRule { + private final ICastingRule keyRule; + private final ICastingRule valueRule; + private final ZenTypeAssociative fromType; + private final ZenTypeAssociative toType; + + public CastingRuleMap(ICastingRule keyRule, ICastingRule valueRule, ZenTypeAssociative fromType, ZenTypeAssociative toType) { + this.keyRule = keyRule; + this.valueRule = valueRule; + this.fromType = fromType; + this.toType = toType; + } + + @Override + public void compile(IEnvironmentMethod method) { + // TODO: implement + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public ZenType getInputType() { + return fromType; + } + + @Override + public ZenType getResultingType() { + return toType; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleMatchedFunction.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleMatchedFunction.java new file mode 100644 index 0000000..0133aeb --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleMatchedFunction.java @@ -0,0 +1,44 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.ZenTypeFunction; + +/** + * + * @author Stan + */ +public class CastingRuleMatchedFunction implements ICastingRule { + private final ZenTypeFunction fromType; + private final ZenType toType; + private final ICastingRule returnCastingRule; + private final ICastingRule[] argumentCastingRules; + + public CastingRuleMatchedFunction(ZenTypeFunction fromType, ZenType toType, ICastingRule returnCastingRule, ICastingRule[] argumentCastingRules) { + this.fromType = fromType; + this.toType = toType; + this.returnCastingRule = returnCastingRule; + this.argumentCastingRules = argumentCastingRules; + } + + @Override + public void compile(IEnvironmentMethod method) { + // nothing to do here + } + + @Override + public ZenType getInputType() { + return fromType; + } + + @Override + public ZenType getResultingType() { + return toType; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleNone.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleNone.java new file mode 100644 index 0000000..4f2568a --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleNone.java @@ -0,0 +1,39 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public class CastingRuleNone implements ICastingRule { + private final ZenType fromType; + private final ZenType toType; + + public CastingRuleNone(ZenType fromType, ZenType toType) { + this.fromType = fromType; + this.toType = toType; + } + + @Override + public void compile(IEnvironmentMethod method) { + // nothing to do + } + + @Override + public ZenType getInputType() { + return fromType; + } + + @Override + public ZenType getResultingType() { + return toType; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleNullableStaticMethod.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleNullableStaticMethod.java new file mode 100644 index 0000000..3b10f27 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleNullableStaticMethod.java @@ -0,0 +1,66 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import org.objectweb.asm.Label; +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.natives.IJavaMethod; +import stanhebben.zenscript.util.MethodOutput; + +/** + * + * @author Stan + */ +public class CastingRuleNullableStaticMethod implements ICastingRule { + private final IJavaMethod method; + private final ICastingRule base; + + public CastingRuleNullableStaticMethod(IJavaMethod method) { + this.method = method; + base = null; + } + + public CastingRuleNullableStaticMethod(IJavaMethod method, ICastingRule base) { + this.method = method; + this.base = base; + } + + @Override + public void compile(IEnvironmentMethod method) { + MethodOutput output = method.getOutput(); + + Label lblNotNull = new Label(); + Label lblAfter = new Label(); + + output.dup(); + output.ifNonNull(lblNotNull); + output.pop(); + output.aConstNull(); + output.goTo(lblAfter); + + output.label(lblNotNull); + + if (base != null) { + base.compile(method); + } + + this.method.invokeStatic(method.getOutput()); + + output.label(lblAfter); + } + + @Override + public ZenType getInputType() { + return method.getParameterTypes()[0]; + } + + @Override + public ZenType getResultingType() { + return method.getReturnType(); + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleNullableVirtualMethod.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleNullableVirtualMethod.java new file mode 100644 index 0000000..9d3598c --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleNullableVirtualMethod.java @@ -0,0 +1,56 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import org.objectweb.asm.Label; +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.natives.IJavaMethod; +import stanhebben.zenscript.util.MethodOutput; + +/** + * + * @author Stan + */ +public class CastingRuleNullableVirtualMethod implements ICastingRule { + private final ZenType type; + private final IJavaMethod method; + + public CastingRuleNullableVirtualMethod(ZenType type, IJavaMethod method) { + this.type = type; + this.method = method; + } + + @Override + public void compile(IEnvironmentMethod method) { + MethodOutput output = method.getOutput(); + + Label lblNotNull = new Label(); + Label lblAfter = new Label(); + + output.dup(); + output.ifNonNull(lblNotNull); + output.pop(); + output.aConstNull(); + output.goTo(lblAfter); + + output.label(lblNotNull); + this.method.invokeVirtual(method.getOutput()); + + output.label(lblAfter); + } + + @Override + public ZenType getInputType() { + return type; + } + + @Override + public ZenType getResultingType() { + return method.getReturnType(); + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleStaticMethod.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleStaticMethod.java new file mode 100644 index 0000000..91b36ef --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleStaticMethod.java @@ -0,0 +1,48 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.natives.IJavaMethod; + +/** + * + * @author Stan + */ +public class CastingRuleStaticMethod implements ICastingRule { + private final IJavaMethod method; + private final ICastingRule base; + + public CastingRuleStaticMethod(IJavaMethod method) { + this.method = method; + this.base = null; + } + + public CastingRuleStaticMethod(IJavaMethod method, ICastingRule base) { + this.method = method; + this.base = base; + } + + @Override + public void compile(IEnvironmentMethod method) { + if (base != null) + base.compile(method); + + this.method.invokeStatic(method.getOutput()); + } + + @Override + public ZenType getInputType() { + return method.getParameterTypes()[0]; + } + + @Override + public ZenType getResultingType() { + return method.getReturnType(); + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleVirtualMethod.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleVirtualMethod.java new file mode 100644 index 0000000..13a16f1 --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/CastingRuleVirtualMethod.java @@ -0,0 +1,38 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.natives.IJavaMethod; + +/** + * + * @author Stan + */ +public class CastingRuleVirtualMethod implements ICastingRule { + private final IJavaMethod method; + + public CastingRuleVirtualMethod(IJavaMethod method) { + this.method = method; + } + + @Override + public void compile(IEnvironmentMethod method) { + this.method.invokeVirtual(method.getOutput()); + } + + @Override + public ZenType getInputType() { + return method.getParameterTypes()[0]; + } + + @Override + public ZenType getResultingType() { + return method.getReturnType(); + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/ICastingRule.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/ICastingRule.java new file mode 100644 index 0000000..6fd781f --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/ICastingRule.java @@ -0,0 +1,22 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.compiler.IEnvironmentMethod; +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public interface ICastingRule { + public void compile(IEnvironmentMethod method); + + public ZenType getInputType(); + + public ZenType getResultingType(); +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/casting/ICastingRuleDelegate.java b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/ICastingRuleDelegate.java new file mode 100644 index 0000000..17449de --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/casting/ICastingRuleDelegate.java @@ -0,0 +1,17 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.casting; + +import stanhebben.zenscript.type.ZenType; + +/** + * + * @author Stan + */ +public interface ICastingRuleDelegate { + public void registerCastingRule(ZenType type, ICastingRule rule); +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/expand/ZenExpandCaster.java b/ZenScript/src/main/java/stanhebben/zenscript/type/expand/ZenExpandCaster.java index a5dc53b..573acd5 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/expand/ZenExpandCaster.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/expand/ZenExpandCaster.java @@ -8,8 +8,12 @@ package stanhebben.zenscript.type.expand; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.expression.Expression; +import stanhebben.zenscript.expression.ExpressionCallStatic; import stanhebben.zenscript.type.ZenType; -import stanhebben.zenscript.type.natives.JavaMethod; +import stanhebben.zenscript.type.casting.CastingRuleDelegateStaticMethod; +import stanhebben.zenscript.type.casting.CastingRuleStaticMethod; +import stanhebben.zenscript.type.casting.ICastingRuleDelegate; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.util.MethodOutput; import stanhebben.zenscript.util.ZenPosition; @@ -18,9 +22,9 @@ import stanhebben.zenscript.util.ZenPosition; * @author Stanneke */ public class ZenExpandCaster { - private final JavaMethod method; + private final IJavaMethod method; - public ZenExpandCaster(JavaMethod method) { + public ZenExpandCaster(IJavaMethod method) { this.method = method; } @@ -28,11 +32,18 @@ public class ZenExpandCaster { return method.getReturnType(); } + public void constructCastingRules(IEnvironmentGlobal environment, ICastingRuleDelegate rules) { + ZenType type = method.getReturnType(); + rules.registerCastingRule(type, new CastingRuleStaticMethod(method)); + + type.constructCastingRules(environment, new CastingRuleDelegateStaticMethod(rules, method), false); + } + public Expression cast(ZenPosition position, IEnvironmentGlobal environment, Expression expression) { - return method.callStatic(position, environment, expression); + return new ExpressionCallStatic(position, environment, method, expression); } public void compile(MethodOutput output) { - output.invokeStatic(method); + method.invokeStatic(output); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/expand/ZenExpandMember.java b/ZenScript/src/main/java/stanhebben/zenscript/type/expand/ZenExpandMember.java index 68dbd06..81da083 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/expand/ZenExpandMember.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/expand/ZenExpandMember.java @@ -11,10 +11,13 @@ import java.util.List; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; +import stanhebben.zenscript.expression.ExpressionCallStatic; +import stanhebben.zenscript.expression.ExpressionCallVirtual; import stanhebben.zenscript.expression.ExpressionInvalid; import stanhebben.zenscript.expression.partial.IPartialExpression; import stanhebben.zenscript.symbols.IZenSymbol; import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.type.natives.JavaMethod; import static stanhebben.zenscript.util.StringUtil.methodMatchingError; import stanhebben.zenscript.util.ZenPosition; @@ -26,9 +29,9 @@ import stanhebben.zenscript.util.ZenPosition; public class ZenExpandMember { private final String type; private final String name; - private JavaMethod getter; - private JavaMethod setter; - private final List methods = new ArrayList(); + private IJavaMethod getter; + private IJavaMethod setter; + private final List methods = new ArrayList(); public ZenExpandMember(String type, String name) { this.type = type; @@ -43,7 +46,7 @@ public class ZenExpandMember { return new StaticGetValue(position); } - public void setGetter(JavaMethod getter) { + public void setGetter(IJavaMethod getter) { if (this.getter != null) { throw new RuntimeException(type + "." + name + " already has a getter"); } else { @@ -51,7 +54,7 @@ public class ZenExpandMember { } } - public void setSetter(JavaMethod setter) { + public void setSetter(IJavaMethod setter) { if (this.setter != null) { throw new RuntimeException(type + "." + name + " already has a setter"); } else { @@ -59,7 +62,7 @@ public class ZenExpandMember { } } - public void addMethod(JavaMethod method) { + public void addMethod(IJavaMethod method) { methods.add(method); } @@ -74,18 +77,17 @@ public class ZenExpandMember { @Override public Expression eval(IEnvironmentGlobal environment) { - return getter.callVirtual(position, environment, value.eval(environment)); + return new ExpressionCallVirtual(position, environment, getter, value.eval(environment)); } @Override public Expression assign(ZenPosition position, IEnvironmentGlobal environment, Expression other) { - return setter.callVirtual(position, environment, value.eval(environment), other); + return new ExpressionCallVirtual(position, environment, setter, value.eval(environment), other); } @Override public IPartialExpression getMember(ZenPosition position, IEnvironmentGlobal environment, String name) { - ZenType type = environment.getType(getter.getMethod().getGenericReturnType()); - return type.getMember(position, environment, this, name); + return getter.getReturnType().getMember(position, environment, this, name); } @Override @@ -93,12 +95,12 @@ public class ZenExpandMember { Expression[] newValues = new Expression[values.length + 1]; newValues[0] = value.eval(environment); System.arraycopy(values, 0, newValues, 1, values.length); - JavaMethod method = JavaMethod.select(true, methods, environment, newValues); + IJavaMethod method = JavaMethod.select(true, methods, environment, newValues); if (method == null) { environment.error(position, methodMatchingError(methods, values)); return new ExpressionInvalid(position); } else { - return method.callStatic(position, environment, newValues); + return new ExpressionCallStatic(position, environment, method, newValues); } } @@ -106,12 +108,28 @@ public class ZenExpandMember { public IZenSymbol toSymbol() { return null; } + + @Override + public ZenType getType() { + return getter.getReturnType(); + } @Override public ZenType toType(IEnvironmentGlobal environment) { environment.error(position, "not a valid type"); return ZenType.ANY; } + + @Override + public ZenType[] predictCallTypes(int numArguments) { + ZenType[] base = JavaMethod.predict(methods, numArguments + 1); + ZenType[] result = new ZenType[base.length - 1]; + for (int i = 0; i < result.length; i++) { + result[i] = base[i + 1]; + } + + return result; + } } private class StaticGetValue implements IPartialExpression { @@ -123,28 +141,27 @@ public class ZenExpandMember { @Override public Expression eval(IEnvironmentGlobal environment) { - return setter.callStatic(position, environment); + return new ExpressionCallStatic(position, environment, getter); } @Override public Expression assign(ZenPosition position, IEnvironmentGlobal environment, Expression other) { - return setter.callStatic(position, environment, other); + return new ExpressionCallStatic(position, environment, setter, other); } @Override public IPartialExpression getMember(ZenPosition position, IEnvironmentGlobal environment, String name) { - ZenType type = environment.getType(getter.getMethod().getGenericReturnType()); - return type.getMember(position, environment, this, name); + return getter.getReturnType().getMember(position, environment, this, name); } @Override public Expression call(ZenPosition position, IEnvironmentMethod environment, Expression... values) { - JavaMethod method = JavaMethod.select(true, methods, environment, values); + IJavaMethod method = JavaMethod.select(true, methods, environment, values); if (method == null) { environment.error(position, methodMatchingError(methods, values)); return new ExpressionInvalid(position); } else { - return method.callStatic(position, environment, values); + return new ExpressionCallStatic(position, environment, method, values); } } @@ -152,12 +169,22 @@ public class ZenExpandMember { public IZenSymbol toSymbol() { return new StaticSymbol(); } + + @Override + public ZenType getType() { + return getter.getReturnType(); + } @Override public ZenType toType(IEnvironmentGlobal environment) { environment.error(position, "not a valid type"); return ZenType.ANY; } + + @Override + public ZenType[] predictCallTypes(int numArguments) { + return JavaMethod.predict(methods, numArguments); + } } private class StaticSymbol implements IZenSymbol { diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/natives/IJavaMethod.java b/ZenScript/src/main/java/stanhebben/zenscript/type/natives/IJavaMethod.java new file mode 100644 index 0000000..5fe0fff --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/natives/IJavaMethod.java @@ -0,0 +1,36 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.natives; + +import stanhebben.zenscript.compiler.IEnvironmentGlobal; +import stanhebben.zenscript.expression.Expression; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.util.MethodOutput; + +/** + * + * @author Stan + */ +public interface IJavaMethod { + public boolean isStatic(); + + public boolean accepts(int numArguments); + + public boolean accepts(IEnvironmentGlobal environment, Expression... arguments); + + public int getPriority(IEnvironmentGlobal environment, Expression... arguments); + + public void invokeVirtual(MethodOutput output); + + public void invokeStatic(MethodOutput output); + + public ZenType[] getParameterTypes(); + + public ZenType getReturnType(); + + public boolean isVarargs(); +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/natives/JavaMethod.java b/ZenScript/src/main/java/stanhebben/zenscript/type/natives/JavaMethod.java index ca733a0..4407e7d 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/natives/JavaMethod.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/natives/JavaMethod.java @@ -15,31 +15,29 @@ import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.ITypeRegistry; import stanhebben.zenscript.expression.Expression; import stanhebben.zenscript.expression.ExpressionArray; -import stanhebben.zenscript.expression.ExpressionInvalid; -import stanhebben.zenscript.expression.ExpressionJavaCallStatic; -import stanhebben.zenscript.expression.ExpressionJavaCallVirtual; import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.type.ZenTypeArray; import stanhebben.zenscript.type.ZenTypeArrayBasic; +import stanhebben.zenscript.util.MethodOutput; import stanhebben.zenscript.util.ZenPosition; /** * * @author Stan */ -public class JavaMethod { +public class JavaMethod implements IJavaMethod { public static final int PRIORITY_INVALID = -1; public static final int PRIORITY_LOW = 1; public static final int PRIORITY_MEDIUM = 2; public static final int PRIORITY_HIGH = 3; - public static JavaMethod get(ITypeRegistry types, Class cls, String name, Class... parameterTypes) { + public static IJavaMethod get(ITypeRegistry types, Class cls, String name, Class... parameterTypes) { try { Method method = cls.getMethod(name, parameterTypes); if (method == null) { throw new RuntimeException("method " + name + " not found in class " + cls.getName()); } - return new JavaMethod(cls, method, types); + return new JavaMethod(method, types); } catch (NoSuchMethodException ex) { throw new RuntimeException("method " + name + " not found in class " + cls.getName(), ex); } catch (SecurityException ex) { @@ -47,12 +45,20 @@ public class JavaMethod { } } - public static JavaMethod select(boolean doStatic, List methods, IEnvironmentGlobal environment, Expression... arguments) { + public static IJavaMethod getStatic(String owner, String name, ZenType returnType, ZenType... arguments) { + return new JavaMethodGenerated(true, false, false, name, owner, returnType, arguments, new boolean[arguments.length]); + } + + public static IJavaMethod get(ITypeRegistry types, Method method) { + return new JavaMethod(method, types); + } + + public static IJavaMethod select(boolean doStatic, List methods, IEnvironmentGlobal environment, Expression... arguments) { int bestPriority = PRIORITY_INVALID; - JavaMethod bestMethod = null; + IJavaMethod bestMethod = null; boolean isValid = false; - for (JavaMethod method : methods) { + for (IJavaMethod method : methods) { if (method.isStatic() != doStatic) continue; int priority = method.getPriority(environment, arguments); @@ -68,29 +74,30 @@ public class JavaMethod { return isValid ? bestMethod : null; } - public static ZenType[] predict(List methods, int numArguments, IEnvironmentGlobal environment) { + public static ZenType[] predict(List methods, int numArguments) { ZenType[] results = new ZenType[numArguments]; boolean[] ambiguous = new boolean[numArguments]; - for (JavaMethod method : methods) { + for (IJavaMethod method : methods) { if (method.accepts(numArguments)) { + ZenType[] parameterTypes = method.getParameterTypes(); for (int i = 0; i < numArguments; i++) { - if (i >= method.parameterTypes.length - 1 && method.method.isVarArgs()) { - if (numArguments == method.parameterTypes.length) { + if (i >= parameterTypes.length - 1 && method.isVarargs()) { + if (numArguments == parameterTypes.length) { ambiguous[i] = true; - } else if (numArguments > method.parameterTypes.length) { + } else if (numArguments > parameterTypes.length) { if (results[i] != null) { ambiguous[i] = true; } else { - results[i] = ((ZenTypeArray) method.parameterTypes[method.parameterTypes.length - 1]).getBaseType(); + results[i] = ((ZenTypeArray) parameterTypes[parameterTypes.length - 1]).getBaseType(); } } - } - - if (results[i] != null) { - ambiguous[i] = true; } else { - results[i] = method.parameterTypes[i]; + if (results[i] != null) { + ambiguous[i] = true; + } else { + results[i] = parameterTypes[i]; + } } } } @@ -105,17 +112,68 @@ public class JavaMethod { return results; } - private final Class owner; + public static Expression[] rematch(ZenPosition position, IJavaMethod method, IEnvironmentGlobal environment, Expression... arguments) { + ZenType[] parameterTypes = method.getParameterTypes(); + + // small optimization - don't run through this all if not necessary + if (arguments.length == 0 && parameterTypes.length == 0) { + return arguments; + } + + Expression[] result = new Expression[method.getParameterTypes().length]; + for (int i = arguments.length; i < method.getParameterTypes().length; i++) { + result[i] = parameterTypes[i].defaultValue(position); + } + + int doUntil = parameterTypes.length; + if (method.isVarargs()) { + doUntil = arguments.length - 1; + ZenType paramType = parameterTypes[parameterTypes.length - 1]; + ZenType baseType = ((ZenTypeArray) paramType).getBaseType(); + + if (arguments.length == parameterTypes.length) { + ZenType argType = arguments[arguments.length - 1].getType(); + + if (argType.equals(paramType)) { + result[arguments.length - 1] = arguments[arguments.length - 1]; + } else if (argType.equals(baseType)) { + result[arguments.length - 1] = new ExpressionArray(position, (ZenTypeArrayBasic) paramType, arguments[arguments.length - 1]); + } else if (argType.canCastImplicit(paramType, environment)) { + result[arguments.length - 1] = arguments[arguments.length - 1].cast(position, environment, paramType); + } else { + result[arguments.length - 1] = new ExpressionArray(position, (ZenTypeArrayBasic) paramType, arguments[arguments.length - 1]).cast(position, environment, paramType); + } + } else if (arguments.length > parameterTypes.length) { + int offset = parameterTypes.length - 1; + Expression[] values = new Expression[arguments.length - offset]; + for (int i = 0; i < values.length; i++) { + values[i] = arguments[offset + i].cast(position, environment, baseType); + } + result[arguments.length - 1] = new ExpressionArray(position, (ZenTypeArrayBasic) paramType, values); + } + } + + for (int i = arguments.length; i < doUntil; i++) { + result[i] = parameterTypes[i].defaultValue(position); + } + for (int i = 0; i < Math.min(arguments.length, doUntil); i++) { + result[i] = arguments[i].cast(position, environment, parameterTypes[i]); + } + + return result; + } + private final Method method; + private final ZenType ownerType; private final ZenType[] parameterTypes; private final boolean[] optional; private final ZenType returnType; - public JavaMethod(Class owner, Method method, ITypeRegistry types) { - this.owner = owner; + public JavaMethod(Method method, ITypeRegistry types) { this.method = method; + ownerType = types.getType(method.getDeclaringClass()); returnType = types.getType(method.getGenericReturnType()); parameterTypes = new ZenType[method.getParameterTypes().length]; optional = new boolean[parameterTypes.length]; @@ -135,30 +193,40 @@ public class JavaMethod { } } + @Override public boolean isStatic() { return (method.getModifiers() & Modifier.STATIC) > 0; } + @Override + public boolean isVarargs() { + return method.isVarArgs(); + } + + @Override public ZenType getReturnType() { return returnType; } + @Override public ZenType[] getParameterTypes() { return parameterTypes; } public Class getOwner() { - return owner; + return method.getDeclaringClass(); } public Method getMethod() { return method; } + @Override public boolean accepts(IEnvironmentGlobal environment, Expression... arguments) { return getPriority(environment, arguments) > 0; } + @Override public boolean accepts(int numArguments) { if (numArguments > parameterTypes.length) { return method.isVarArgs(); @@ -172,6 +240,7 @@ public class JavaMethod { } } + @Override public int getPriority(IEnvironmentGlobal environment, Expression... arguments) { int result = PRIORITY_HIGH; if (arguments.length > parameterTypes.length) { @@ -241,73 +310,38 @@ public class JavaMethod { return result; } - - public Expression callVirtual(ZenPosition position, IEnvironmentGlobal environment, Expression receiver, Expression... arguments) { + + @Override + public void invokeVirtual(MethodOutput output) { if (isStatic()) { - environment.error(position, "trying to call a static method dynamically"); - return new ExpressionInvalid(position, environment.getType(method.getReturnType())); + throw new UnsupportedOperationException("Method is static"); } else { - Expression[] actual = rematch(position, environment, arguments); - return new ExpressionJavaCallVirtual(position, this, receiver, actual); - } - } - - public Expression callStatic(ZenPosition position, IEnvironmentGlobal environment, Expression... arguments) { - if (isStatic()) { - Expression[] actual = rematch(position, environment, arguments); - return new ExpressionJavaCallStatic(position, this, actual); - } else { - environment.error(position, "trying to call a non-static method statically"); - return new ExpressionInvalid(position, environment.getType(method.getReturnType())); - } - } - - private Expression[] rematch(ZenPosition position, IEnvironmentGlobal environment, Expression... arguments) { - // small optimization - don't run through this all if not necessary - if (arguments.length == 0 && parameterTypes.length == 0) { - return arguments; - } - - Expression[] result = new Expression[method.getParameterTypes().length]; - for (int i = arguments.length; i < method.getParameterTypes().length; i++) { - result[i] = parameterTypes[i].defaultValue(position); - } - - int doUntil = parameterTypes.length; - if (method.isVarArgs()) { - doUntil = arguments.length - 1; - ZenType paramType = parameterTypes[parameterTypes.length - 1]; - ZenType baseType = ((ZenTypeArray) paramType).getBaseType(); - - if (arguments.length == parameterTypes.length) { - ZenType argType = arguments[arguments.length - 1].getType(); - - if (argType.equals(paramType)) { - result[arguments.length - 1] = arguments[arguments.length - 1]; - } else if (argType.equals(baseType)) { - result[arguments.length - 1] = new ExpressionArray(position, arguments[arguments.length - 1]); - } else if (argType.canCastImplicit(paramType, environment)) { - result[arguments.length - 1] = arguments[arguments.length - 1].cast(position, environment, paramType); - } else { - result[arguments.length - 1] = new ExpressionArray(position, arguments[arguments.length - 1]).cast(position, environment, paramType); - } - } else if (arguments.length > parameterTypes.length) { - int offset = parameterTypes.length - 1; - Expression[] values = new Expression[arguments.length - offset]; - for (int i = 0; i < values.length; i++) { - values[i] = arguments[offset + i].cast(position, environment, baseType); - } - result[arguments.length - 1] = new ExpressionArray(position, values, (ZenTypeArrayBasic) paramType); + if (method.getDeclaringClass().isInterface()) { + output.invokeInterface( + method.getDeclaringClass(), + method.getName(), + method.getReturnType(), + method.getParameterTypes()); + } else { + output.invokeVirtual( + method.getDeclaringClass(), + method.getName(), + method.getReturnType(), + method.getParameterTypes()); } } - - for (int i = arguments.length; i < doUntil; i++) { - result[i] = parameterTypes[i].defaultValue(position); + } + + @Override + public void invokeStatic(MethodOutput output) { + if (!isStatic()) { + throw new UnsupportedOperationException("Method is not static"); + } else { + output.invokeStatic( + method.getDeclaringClass(), + method.getName(), + method.getReturnType(), + method.getParameterTypes()); } - for (int i = 0; i < Math.min(arguments.length, doUntil); i++) { - result[i] = arguments[i].cast(position, environment, parameterTypes[i]); - } - - return result; } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/natives/JavaMethodGenerated.java b/ZenScript/src/main/java/stanhebben/zenscript/type/natives/JavaMethodGenerated.java new file mode 100644 index 0000000..b0d6c4c --- /dev/null +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/natives/JavaMethodGenerated.java @@ -0,0 +1,196 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package stanhebben.zenscript.type.natives; + +import stanhebben.zenscript.compiler.IEnvironmentGlobal; +import stanhebben.zenscript.expression.Expression; +import stanhebben.zenscript.type.ZenType; +import stanhebben.zenscript.type.ZenTypeArray; +import static stanhebben.zenscript.type.natives.JavaMethod.PRIORITY_HIGH; +import static stanhebben.zenscript.type.natives.JavaMethod.PRIORITY_INVALID; +import static stanhebben.zenscript.type.natives.JavaMethod.PRIORITY_LOW; +import static stanhebben.zenscript.type.natives.JavaMethod.PRIORITY_MEDIUM; +import stanhebben.zenscript.util.MethodOutput; + +/** + * + * @author Stan + */ +public class JavaMethodGenerated implements IJavaMethod { + private final boolean isStatic; + private final boolean isInterface; + private final boolean isVarargs; + private final String owner; + private final String name; + + private final ZenType[] parameterTypes; + private final boolean[] optional; + private final ZenType returnType; + + private final String descriptor; + + public JavaMethodGenerated( + boolean isStatic, + boolean isInterface, + boolean isVarargs, + String owner, + String name, + ZenType returnType, + ZenType[] arguments, + boolean[] optional) { + this.isStatic = isStatic; + this.isInterface = isInterface; + this.isVarargs = isVarargs; + this.owner = owner; + this.name = name; + + this.returnType = returnType; + this.parameterTypes = arguments; + this.optional = optional; + + StringBuilder descriptorString = new StringBuilder(); + descriptorString.append('('); + for (ZenType argument : arguments) { + descriptorString.append(argument.getSignature()); + } + descriptorString.append(')'); + descriptorString.append(returnType.getSignature()); + descriptor = descriptorString.toString(); + } + + @Override + public boolean isStatic() { + return isStatic; + } + + @Override + public boolean isVarargs() { + return isVarargs; + } + + @Override + public boolean accepts(int numArguments) { + if (numArguments > parameterTypes.length) { + return isVarargs; + } if (numArguments == parameterTypes.length) { + return true; + } else { + for (int i = numArguments; i < parameterTypes.length; i++) { + if (!optional[i]) return false; + } + return true; + } + } + + @Override + public boolean accepts(IEnvironmentGlobal environment, Expression... arguments) { + return getPriority(environment, arguments) > 0; + } + + @Override + public int getPriority(IEnvironmentGlobal environment, Expression... arguments) { + int result = PRIORITY_HIGH; + if (arguments.length > parameterTypes.length) { + if (isVarargs) { + ZenType arrayType = parameterTypes[parameterTypes.length - 1]; + ZenType baseType = ((ZenTypeArray) arrayType).getBaseType(); + for (int i = parameterTypes.length - 1; i < arguments.length; i++) { + ZenType argType = arguments[i].getType(); + if (argType.equals(baseType)) { + // OK + } else if (argType.canCastImplicit(baseType, environment)) { + result = Math.min(result, PRIORITY_LOW); + } else { + return PRIORITY_INVALID; + } + } + } else { + return PRIORITY_INVALID; + } + } else if (arguments.length < parameterTypes.length) { + result = PRIORITY_MEDIUM; + + int checkUntil = parameterTypes.length; + if (isVarargs) { + checkUntil--; + } + + checkOptional: for (int i = arguments.length; i < checkUntil; i++) { + if (!optional[i]) { + return PRIORITY_INVALID; + } + } + } + + int checkUntil = arguments.length; + if (arguments.length == parameterTypes.length && isVarargs) { + ZenType arrayType = parameterTypes[parameterTypes.length - 1]; + ZenType baseType = ((ZenTypeArray) arrayType).getBaseType(); + ZenType argType = arguments[arguments.length - 1].getType(); + + if (argType.equals(arrayType)) { + // OK + } else if (argType.equals(baseType)) { + // OK + } else if (argType.canCastImplicit(arrayType, environment)) { + result = Math.min(result, PRIORITY_LOW); + } else if (argType.canCastImplicit(baseType, environment)) { + result = Math.min(result, PRIORITY_LOW); + } else { + return PRIORITY_INVALID; + } + + checkUntil = arguments.length - 1; + } + + for (int i = 0; i < checkUntil; i++) { + ZenType argType = arguments[i].getType(); + ZenType paramType = parameterTypes[i]; + if (!argType.equals(paramType)) { + if (argType.canCastImplicit(paramType, environment)) { + result = Math.min(result, PRIORITY_LOW); + } else { + return PRIORITY_INVALID; + } + } + } + + return result; + } + + @Override + public void invokeVirtual(MethodOutput output) { + if (isStatic) { + throw new UnsupportedOperationException("Not supported yet."); + } else { + if (isInterface) { + output.invokeInterface(owner, name, descriptor); + } else { + output.invokeVirtual(owner, name, descriptor); + } + } + } + + @Override + public void invokeStatic(MethodOutput output) { + if (!isStatic) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } else { + output.invokeStatic(owner, name, descriptor); + } + } + + @Override + public ZenType getReturnType() { + return returnType; + } + + @Override + public ZenType[] getParameterTypes() { + return parameterTypes; + } +} diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/natives/ZenNativeCaster.java b/ZenScript/src/main/java/stanhebben/zenscript/type/natives/ZenNativeCaster.java index c399110..dd93054 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/natives/ZenNativeCaster.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/natives/ZenNativeCaster.java @@ -6,6 +6,9 @@ package stanhebben.zenscript.type.natives; +import org.objectweb.asm.Label; +import stanhebben.zenscript.compiler.IEnvironmentGlobal; +import stanhebben.zenscript.type.ZenType; import stanhebben.zenscript.util.MethodOutput; /** @@ -13,21 +16,66 @@ import stanhebben.zenscript.util.MethodOutput; * @author Stanneke */ public class ZenNativeCaster { - private final Class owner; - private final Class output; - private final String methodName; + private final IJavaMethod method; - public ZenNativeCaster(Class owner, Class output, String methodName) { - this.owner = owner; - this.output = output; - this.methodName = methodName; + public ZenNativeCaster(IJavaMethod method) { + this.method = method; } - public Class getCasterClass() { - return output; + public ZenType getReturnType() { + return method.getReturnType(); } public void compile(MethodOutput output) { - output.invoke(owner, methodName, this.output); + if (method.isStatic()) { + method.invokeStatic(output); + } else { + method.invokeVirtual(output); + } + } + + public void compileAnyCanCastImplicit(ZenType type, MethodOutput output, IEnvironmentGlobal environment, int localClass) { + String casterAny = method.getReturnType().getAnyClassName(environment); + if (casterAny == null) { + // TODO: make sure no type ever does this + return; + } + + Label skip = new Label(); + output.loadObject(localClass); + output.invokeStatic(casterAny, "rtCanCastImplicit", "(Ljava/lang/Class;)Z"); + output.ifEQ(skip); + output.iConst1(); + output.returnInt(); + output.label(skip); + } + + public void compileAnyCast(ZenType type, MethodOutput output, IEnvironmentGlobal environment, int localValue, int localClass) { + Label skip = new Label(); + output.loadObject(localClass); + output.constant(method.getReturnType().toASMType()); + output.ifACmpNe(skip); + output.load(type.toASMType(), localValue); + + compile(output); + + output.returnType(method.getReturnType().toASMType()); + output.label(skip); + + String casterAny = method.getReturnType().getAnyClassName(environment); + if (casterAny == null) + // TODO: make sure this isn't necessary + return; + + Label skip2 = new Label(); + output.loadObject(localClass); + output.invokeStatic(casterAny, "rtCanCastImplicit", "(Ljava/lang/Class;)Z"); + output.ifEQ(skip2); + output.load(type.toASMType(), localValue); + + compile(output); + + output.returnType(method.getReturnType().toASMType()); + output.label(skip2); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/natives/ZenNativeMember.java b/ZenScript/src/main/java/stanhebben/zenscript/type/natives/ZenNativeMember.java index 13bd36f..fcc7b56 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/natives/ZenNativeMember.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/natives/ZenNativeMember.java @@ -11,6 +11,8 @@ import java.util.List; import stanhebben.zenscript.compiler.IEnvironmentGlobal; import stanhebben.zenscript.compiler.IEnvironmentMethod; import stanhebben.zenscript.expression.Expression; +import stanhebben.zenscript.expression.ExpressionCallStatic; +import stanhebben.zenscript.expression.ExpressionCallVirtual; import stanhebben.zenscript.expression.ExpressionInvalid; import stanhebben.zenscript.expression.partial.IPartialExpression; import stanhebben.zenscript.symbols.IZenSymbol; @@ -23,19 +25,19 @@ import stanhebben.zenscript.util.ZenPosition; * @author Stan */ public class ZenNativeMember { - private JavaMethod getter; - private JavaMethod setter; - private final List methods = new ArrayList(); + private IJavaMethod getter; + private IJavaMethod setter; + private final List methods = new ArrayList(); - public JavaMethod getGetter() { + public IJavaMethod getGetter() { return getter; } - public JavaMethod getSetter() { + public IJavaMethod getSetter() { return setter; } - public void setGetter(JavaMethod getter) { + public void setGetter(IJavaMethod getter) { if (this.getter == null) { this.getter = getter; } else { @@ -43,7 +45,7 @@ public class ZenNativeMember { } } - public void setSetter(JavaMethod setter) { + public void setSetter(IJavaMethod setter) { if (this.setter == null) { this.setter = setter; } else { @@ -74,35 +76,44 @@ public class ZenNativeMember { @Override public Expression eval(IEnvironmentGlobal environment) { - return getter.callVirtual(position, environment, value.eval(environment)); + return new ExpressionCallVirtual(position, environment, getter, value.eval(environment)); } @Override public Expression assign(ZenPosition position, IEnvironmentGlobal environment, Expression other) { - return setter.callVirtual(position, environment, value.eval(environment), other); + return new ExpressionCallVirtual(position, environment, setter, value.eval(environment), other); } @Override public IPartialExpression getMember(ZenPosition position, IEnvironmentGlobal environment, String name) { - ZenType type = environment.getType(getter.getMethod().getGenericReturnType()); - return type.getMember(position, environment, this, name); + return getter.getReturnType().getMember(position, environment, this, name); } @Override public Expression call(ZenPosition position, IEnvironmentMethod environment, Expression... values) { - JavaMethod method = JavaMethod.select(false, methods, environment, values); + IJavaMethod method = JavaMethod.select(false, methods, environment, values); if (method == null) { environment.error(position, methodMatchingError(methods, values)); return new ExpressionInvalid(position); } else { - return method.callVirtual(position, environment, value.eval(environment), values); + return new ExpressionCallVirtual(position, environment, method, value.eval(environment), values); } } - + + @Override + public ZenType[] predictCallTypes(int numArguments) { + return JavaMethod.predict(methods, numArguments); + } + @Override public IZenSymbol toSymbol() { return null; } + + @Override + public ZenType getType() { + return getter.getReturnType(); + } @Override public ZenType toType(IEnvironmentGlobal environment) { @@ -120,35 +131,44 @@ public class ZenNativeMember { @Override public Expression eval(IEnvironmentGlobal environment) { - return setter.callStatic(position, environment); + return new ExpressionCallStatic(position, environment, setter); } @Override public Expression assign(ZenPosition position, IEnvironmentGlobal environment, Expression other) { - return setter.callStatic(position, environment, other); + return new ExpressionCallStatic(position, environment, setter); } @Override public IPartialExpression getMember(ZenPosition position, IEnvironmentGlobal environment, String name) { - ZenType type = environment.getType(getter.getMethod().getGenericReturnType()); - return type.getMember(position, environment, this, name); + return getter.getReturnType().getMember(position, environment, this, name); } @Override public Expression call(ZenPosition position, IEnvironmentMethod environment, Expression... values) { - JavaMethod method = JavaMethod.select(true, methods, environment, values); + IJavaMethod method = JavaMethod.select(true, methods, environment, values); if (method == null) { environment.error(position, methodMatchingError(methods, values)); return new ExpressionInvalid(position); } else { - return method.callStatic(position, environment, values); + return new ExpressionCallStatic(position, environment, method, values); } } + + @Override + public ZenType[] predictCallTypes(int numArguments) { + return JavaMethod.predict(methods, numArguments); + } @Override public IZenSymbol toSymbol() { return new StaticSymbol(); } + + @Override + public ZenType getType() { + return getter.getReturnType(); + } @Override public ZenType toType(IEnvironmentGlobal environment) { diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/natives/ZenNativeOperator.java b/ZenScript/src/main/java/stanhebben/zenscript/type/natives/ZenNativeOperator.java index b7a0aa5..390d140 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/natives/ZenNativeOperator.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/natives/ZenNativeOperator.java @@ -14,9 +14,9 @@ import stanhebben.zenscript.annotations.OperatorType; */ public class ZenNativeOperator { private final OperatorType operator; - private final JavaMethod method; + private final IJavaMethod method; - public ZenNativeOperator(OperatorType operator, JavaMethod method) { + public ZenNativeOperator(OperatorType operator, IJavaMethod method) { this.operator = operator; this.method = method; } @@ -25,7 +25,7 @@ public class ZenNativeOperator { return operator; } - public JavaMethod getMethod() { + public IJavaMethod getMethod() { return method; } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/util/AnyClassWriter.java b/ZenScript/src/main/java/stanhebben/zenscript/util/AnyClassWriter.java index 2713381..81a0a3f 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/util/AnyClassWriter.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/util/AnyClassWriter.java @@ -10,6 +10,7 @@ import java.util.Iterator; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; +import stanhebben.zenscript.type.natives.IJavaMethod; import stanhebben.zenscript.type.natives.JavaMethod; import static stanhebben.zenscript.util.ZenTypeUtil.EMPTY_REGISTRY; import static stanhebben.zenscript.util.ZenTypeUtil.internal; @@ -21,40 +22,40 @@ import stanhebben.zenscript.value.IAny; * @author Stan */ public class AnyClassWriter { - public static final JavaMethod METHOD_NOT = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "not"); - public static final JavaMethod METHOD_NEG = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "neg"); - public static final JavaMethod METHOD_ADD = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "add", IAny.class); - public static final JavaMethod METHOD_CAT = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "cat", IAny.class); - public static final JavaMethod METHOD_SUB = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "sub", IAny.class); - public static final JavaMethod METHOD_MUL = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "mul", IAny.class); - public static final JavaMethod METHOD_DIV = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "div", IAny.class); - public static final JavaMethod METHOD_MOD = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "mod", IAny.class); - public static final JavaMethod METHOD_AND = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "and", IAny.class); - public static final JavaMethod METHOD_OR = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "or", IAny.class); - public static final JavaMethod METHOD_XOR = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "xor", IAny.class); - public static final JavaMethod METHOD_RANGE = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "range", IAny.class); - public static final JavaMethod METHOD_COMPARETO = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "compareTo", IAny.class); - public static final JavaMethod METHOD_CONTAINS = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "contains", IAny.class); - public static final JavaMethod METHOD_MEMBERGET = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "memberGet", String.class); - public static final JavaMethod METHOD_MEMBERSET = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "memberSet", String.class, IAny.class); - public static final JavaMethod METHOD_MEMBERCALL = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "memberCall", String.class, IAny[].class); - public static final JavaMethod METHOD_INDEXGET = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "indexGet", IAny.class); - public static final JavaMethod METHOD_INDEXSET = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "indexSet", IAny.class, IAny.class); - public static final JavaMethod METHOD_CALL = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "call", IAny[].class); - public static final JavaMethod METHOD_ASBOOL = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "asBool"); - public static final JavaMethod METHOD_ASBYTE = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "asByte"); - public static final JavaMethod METHOD_ASSHORT = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "asShort"); - public static final JavaMethod METHOD_ASINT = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "asInt"); - public static final JavaMethod METHOD_ASLONG = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "asLong"); - public static final JavaMethod METHOD_ASFLOAT = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "asFloat"); - public static final JavaMethod METHOD_ASDOUBLE = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "asDouble"); - public static final JavaMethod METHOD_ASSTRING = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "asString"); - public static final JavaMethod METHOD_AS = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "as", Class.class); - public static final JavaMethod METHOD_IS = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "is", Class.class); - public static final JavaMethod METHOD_CANCASTIMPLICIT = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "canCastImplicit", Class.class); - public static final JavaMethod METHOD_GETNUMBERTYPE = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "getNumberType"); - public static final JavaMethod METHOD_ITERATORSINGLE = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "iteratorSingle"); - public static final JavaMethod METHOD_ITERATORMULTI = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "iteratorMulti", int.class); + public static final IJavaMethod METHOD_NOT = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "not"); + public static final IJavaMethod METHOD_NEG = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "neg"); + public static final IJavaMethod METHOD_ADD = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "add", IAny.class); + public static final IJavaMethod METHOD_CAT = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "cat", IAny.class); + public static final IJavaMethod METHOD_SUB = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "sub", IAny.class); + public static final IJavaMethod METHOD_MUL = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "mul", IAny.class); + public static final IJavaMethod METHOD_DIV = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "div", IAny.class); + public static final IJavaMethod METHOD_MOD = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "mod", IAny.class); + public static final IJavaMethod METHOD_AND = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "and", IAny.class); + public static final IJavaMethod METHOD_OR = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "or", IAny.class); + public static final IJavaMethod METHOD_XOR = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "xor", IAny.class); + public static final IJavaMethod METHOD_RANGE = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "range", IAny.class); + public static final IJavaMethod METHOD_COMPARETO = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "compareTo", IAny.class); + public static final IJavaMethod METHOD_CONTAINS = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "contains", IAny.class); + public static final IJavaMethod METHOD_MEMBERGET = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "memberGet", String.class); + public static final IJavaMethod METHOD_MEMBERSET = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "memberSet", String.class, IAny.class); + public static final IJavaMethod METHOD_MEMBERCALL = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "memberCall", String.class, IAny[].class); + public static final IJavaMethod METHOD_INDEXGET = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "indexGet", IAny.class); + public static final IJavaMethod METHOD_INDEXSET = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "indexSet", IAny.class, IAny.class); + public static final IJavaMethod METHOD_CALL = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "call", IAny[].class); + public static final IJavaMethod METHOD_ASBOOL = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "asBool"); + public static final IJavaMethod METHOD_ASBYTE = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "asByte"); + public static final IJavaMethod METHOD_ASSHORT = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "asShort"); + public static final IJavaMethod METHOD_ASINT = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "asInt"); + public static final IJavaMethod METHOD_ASLONG = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "asLong"); + public static final IJavaMethod METHOD_ASFLOAT = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "asFloat"); + public static final IJavaMethod METHOD_ASDOUBLE = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "asDouble"); + public static final IJavaMethod METHOD_ASSTRING = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "asString"); + public static final IJavaMethod METHOD_AS = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "as", Class.class); + public static final IJavaMethod METHOD_IS = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "is", Class.class); + public static final IJavaMethod METHOD_CANCASTIMPLICIT = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "canCastImplicit", Class.class); + public static final IJavaMethod METHOD_GETNUMBERTYPE = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "getNumberType"); + public static final IJavaMethod METHOD_ITERATORSINGLE = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "iteratorSingle"); + public static final IJavaMethod METHOD_ITERATORMULTI = JavaMethod.get(EMPTY_REGISTRY, IAny.class, "iteratorMulti", int.class); private static final String SIG_ANY = "()" + signature(IAny.class); private static final String SIG_ANY_ANY = "(" + signature(IAny.class) + ")" + signature(IAny.class); @@ -69,343 +70,348 @@ public class AnyClassWriter { private AnyClassWriter() {} public static byte[] construct(IAnyDefinition definition, String name, Type asmType) { - ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES); - writer.visit( - Opcodes.V1_6, - Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, - name, - null, - internal(Object.class), - new String[] { internal(IAny.class) }); - - definition.defineMembers(writer); - - MethodOutput outputStaticCanCastImplicit = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, - "rtCanCastImplicit", - "(Ljava/lang/Class;)Z", - "(Ljava/lang/Class<*>;)Z", - null); - outputStaticCanCastImplicit.start(); - definition.defineStaticCanCastImplicit(outputStaticCanCastImplicit); - outputStaticCanCastImplicit.end(); - - MethodOutput outputStaticAs = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, - "rtAs", - "(ILjava/lang/Class;)Ljava/lang/Object;", - "(ILjava/lang/Class<*>;)Ljava/lang/Object;", - null); - outputStaticAs.start(); - definition.defineStaticAs(outputStaticAs); - outputStaticAs.end(); - - MethodOutput outputNot = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "not", - SIG_ANY, - null, - null); - outputNot.start(); - definition.defineNot(outputNot); - outputNot.end(); - - MethodOutput outputNeg = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "neg", - SIG_ANY, - null, - null); - outputNeg.start(); - definition.defineNeg(outputNeg); - outputNeg.end(); - - MethodOutput outputAdd = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "add", - SIG_ANY_ANY, - null, - null); - outputAdd.start(); - definition.defineAdd(outputAdd); - outputAdd.end(); - - MethodOutput outputSub = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "sub", - SIG_ANY_ANY, - null, - null); - outputSub.start(); - definition.defineSub(outputSub); - outputSub.end(); - - MethodOutput outputCat = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "cat", - SIG_ANY_ANY, - null, - null); - outputCat.start(); - definition.defineCat(outputCat); - outputCat.end(); - - MethodOutput outputMul = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "mul", - SIG_ANY_ANY, - null, - null); - outputMul.start(); - definition.defineMul(outputMul); - outputMul.end(); - - MethodOutput outputDiv = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "div", - SIG_ANY_ANY, - null, - null); - outputDiv.start(); - definition.defineDiv(outputDiv); - outputDiv.end(); - - MethodOutput outputMod = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "mod", - SIG_ANY_ANY, - null, - null); - outputMod.start(); - definition.defineMod(outputMod); - outputMod.end(); - - MethodOutput outputAnd = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "and", - SIG_ANY_ANY, - null, - null); - outputAnd.start(); - definition.defineAnd(outputAnd); - outputAnd.end(); - - MethodOutput outputOr = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "or", - SIG_ANY_ANY, - null, - null); - outputOr.start(); - definition.defineOr(outputOr); - outputOr.end(); - - MethodOutput outputXor = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "xor", - SIG_ANY_ANY, - null, - null); - outputXor.start(); - definition.defineXor(outputXor); - outputXor.end(); - - MethodOutput outputRange = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "range", - SIG_ANY_ANY, - null, - null); - outputRange.start(); - definition.defineRange(outputRange); - outputRange.end(); - - MethodOutput outputCompare = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "compareTo", - SIG_ANY_INT, - null, - null); - outputCompare.start(); - definition.defineCompareTo(outputCompare); - outputCompare.end(); - - MethodOutput outputContains = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "contains", - SIG_ANY_BOOL, - null, - null); - outputContains.start(); - definition.defineContains(outputContains); - outputContains.end(); - - MethodOutput outputMemberGet = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "memberGet", SIG_STRING_ANY, null, null); - outputMemberGet.start(); - definition.defineMemberGet(outputMemberGet); - outputMemberGet.end(); - - MethodOutput outputMemberSet = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "memberSet", SIG_STRING_ANY_VOID, null, null); - outputMemberSet.start(); - definition.defineMemberSet(outputMemberSet); - outputMemberSet.end(); - - MethodOutput outputMemberCall = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "memberCall", SIG_STRING_ANYARRAY_ANY, null, null); - outputMemberCall.start(); - definition.defineMemberCall(outputMemberCall); - outputMemberCall.end(); - - MethodOutput outputIndexGet = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "indexGet", SIG_ANY_ANY, null, null); - outputIndexGet.start(); - definition.defineIndexGet(outputIndexGet); - outputIndexGet.end(); - - MethodOutput outputIndexSet = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "indexSet", SIG_ANY_ANY_VOID, null, null); - outputIndexSet.start(); - definition.defineIndexSet(outputIndexSet); - outputIndexSet.end(); - - MethodOutput outputCall = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "call", SIG_ANYARRAY_ANY, null, null); - outputCall.start(); - definition.defineCall(outputCall); - outputCall.end(); - - MethodOutput outputAsBool = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "asBool", "()Z", null, null); - outputAsBool.start(); - definition.defineAsBool(outputAsBool); - outputAsBool.end(); - - MethodOutput outputAsByte = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "asByte", "()B", null, null); - outputAsByte.start(); - definition.defineAsByte(outputAsByte); - outputAsByte.end(); - - MethodOutput outputAsShort = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "asShort", "()S", null, null); - outputAsShort.start(); - definition.defineAsShort(outputAsShort); - outputAsShort.end(); - - MethodOutput outputAsInt = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "asInt", "()I", null, null); - outputAsInt.start(); - definition.defineAsInt(outputAsInt); - outputAsInt.end(); - - MethodOutput outputAsLong = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "asLong", "()J", null, null); - outputAsLong.start(); - definition.defineAsLong(outputAsLong); - outputAsLong.end(); - - MethodOutput outputAsFloat = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "asFloat", "()F", null, null); - outputAsFloat.start(); - definition.defineAsFloat(outputAsFloat); - outputAsFloat.end(); - - MethodOutput outputAsDouble = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "asDouble", "()D", null, null); - outputAsDouble.start(); - definition.defineAsDouble(outputAsDouble); - outputAsDouble.end(); - - MethodOutput outputAsString = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "asString", "()Ljava/lang/String;", null, null); - outputAsString.start(); - definition.defineAsString(outputAsString); - outputAsString.end(); - - MethodOutput outputAs = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "as", - "(Ljava/lang/Class;)" + signature(IAny.class), - "(Ljava/lang/Class;)TT;", - null); - outputAs.start(); - definition.defineAs(outputAs); - outputAs.end(); - - MethodOutput outputIs = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "is", - "(Ljava/lang/Class;)Z", - "(Ljava/lang/Class<*>;)Z", - null); - outputIs.start(); - definition.defineIs(outputIs); - outputIs.end(); - - MethodOutput outputCanCastImplicit = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "canCastImplicit", "(" + signature(Class.class) + ")Z", "(Ljava/lang/Class<*>;)Z", null); - outputCanCastImplicit.start(); - outputCanCastImplicit.loadObject(1); - outputCanCastImplicit.invokeStatic(name, "rtCanCastImplicit", "(Ljava/lang/Class;)Z"); - outputCanCastImplicit.returnInt(); - outputCanCastImplicit.end(); - - MethodOutput outputGetNumberType = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "getNumberType", "()I", null, null); - outputGetNumberType.start(); - definition.defineGetNumberType(outputGetNumberType); - outputGetNumberType.end(); - - MethodOutput outputIteratorSingle = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "iteratorSingle", - "()" + signature(Iterator.class), - "()Ljava/util/Iterator;", - null); - outputIteratorSingle.start(); - definition.defineIteratorSingle(outputIteratorSingle); - outputIteratorSingle.end(); - - MethodOutput outputIteratorMulti = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "iteratorMulti", - "(I)Ljava/util/Iterator;", - "(I)Ljava/util/Iterator<[Lstanhebben/zenscript/value/IAny;>;", - null); - outputIteratorMulti.start(); - definition.defineIteratorMulti(outputIteratorMulti); - outputIteratorMulti.end(); - - MethodOutput outputHashCode = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "hashCode", - "()I", - null, - null); - outputHashCode.start(); - definition.defineHashCode(outputHashCode); - outputHashCode.end(); - - MethodOutput outputEquals = new MethodOutput( - writer, - Opcodes.ACC_PUBLIC, - "equals", - "(Ljava/lang/Object;)Z", - null, - null); - outputEquals.start(); - definition.defineEquals(outputEquals); - outputEquals.end(); - - writer.visitEnd(); - return writer.toByteArray(); + try { + ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES); + writer.visit( + Opcodes.V1_6, + Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, + name, + null, + internal(Object.class), + new String[] { internal(IAny.class) }); + + definition.defineMembers(writer); + + MethodOutput outputStaticCanCastImplicit = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, + "rtCanCastImplicit", + "(Ljava/lang/Class;)Z", + "(Ljava/lang/Class<*>;)Z", + null); + outputStaticCanCastImplicit.start(); + definition.defineStaticCanCastImplicit(outputStaticCanCastImplicit); + outputStaticCanCastImplicit.end(); + + MethodOutput outputStaticAs = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, + "rtAs", + "(" + asmType.getDescriptor() + "Ljava/lang/Class;)Ljava/lang/Object;", + "(" + asmType.getDescriptor() + "Ljava/lang/Class<*>;)Ljava/lang/Object;", + null); + outputStaticAs.start(); + definition.defineStaticAs(outputStaticAs); + outputStaticAs.end(); + + MethodOutput outputNot = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "not", + SIG_ANY, + null, + null); + outputNot.start(); + definition.defineNot(outputNot); + outputNot.end(); + + MethodOutput outputNeg = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "neg", + SIG_ANY, + null, + null); + outputNeg.start(); + definition.defineNeg(outputNeg); + outputNeg.end(); + + MethodOutput outputAdd = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "add", + SIG_ANY_ANY, + null, + null); + outputAdd.start(); + definition.defineAdd(outputAdd); + outputAdd.end(); + + MethodOutput outputSub = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "sub", + SIG_ANY_ANY, + null, + null); + outputSub.start(); + definition.defineSub(outputSub); + outputSub.end(); + + MethodOutput outputCat = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "cat", + SIG_ANY_ANY, + null, + null); + outputCat.start(); + definition.defineCat(outputCat); + outputCat.end(); + + MethodOutput outputMul = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "mul", + SIG_ANY_ANY, + null, + null); + outputMul.start(); + definition.defineMul(outputMul); + outputMul.end(); + + MethodOutput outputDiv = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "div", + SIG_ANY_ANY, + null, + null); + outputDiv.start(); + definition.defineDiv(outputDiv); + outputDiv.end(); + + MethodOutput outputMod = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "mod", + SIG_ANY_ANY, + null, + null); + outputMod.start(); + definition.defineMod(outputMod); + outputMod.end(); + + MethodOutput outputAnd = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "and", + SIG_ANY_ANY, + null, + null); + outputAnd.start(); + definition.defineAnd(outputAnd); + outputAnd.end(); + + MethodOutput outputOr = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "or", + SIG_ANY_ANY, + null, + null); + outputOr.start(); + definition.defineOr(outputOr); + outputOr.end(); + + MethodOutput outputXor = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "xor", + SIG_ANY_ANY, + null, + null); + outputXor.start(); + definition.defineXor(outputXor); + outputXor.end(); + + MethodOutput outputRange = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "range", + SIG_ANY_ANY, + null, + null); + outputRange.start(); + definition.defineRange(outputRange); + outputRange.end(); + + MethodOutput outputCompare = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "compareTo", + SIG_ANY_INT, + null, + null); + outputCompare.start(); + definition.defineCompareTo(outputCompare); + outputCompare.end(); + + MethodOutput outputContains = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "contains", + SIG_ANY_BOOL, + null, + null); + outputContains.start(); + definition.defineContains(outputContains); + outputContains.end(); + + MethodOutput outputMemberGet = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "memberGet", SIG_STRING_ANY, null, null); + outputMemberGet.start(); + definition.defineMemberGet(outputMemberGet); + outputMemberGet.end(); + + MethodOutput outputMemberSet = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "memberSet", SIG_STRING_ANY_VOID, null, null); + outputMemberSet.start(); + definition.defineMemberSet(outputMemberSet); + outputMemberSet.end(); + + MethodOutput outputMemberCall = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "memberCall", SIG_STRING_ANYARRAY_ANY, null, null); + outputMemberCall.start(); + definition.defineMemberCall(outputMemberCall); + outputMemberCall.end(); + + MethodOutput outputIndexGet = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "indexGet", SIG_ANY_ANY, null, null); + outputIndexGet.start(); + definition.defineIndexGet(outputIndexGet); + outputIndexGet.end(); + + MethodOutput outputIndexSet = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "indexSet", SIG_ANY_ANY_VOID, null, null); + outputIndexSet.start(); + definition.defineIndexSet(outputIndexSet); + outputIndexSet.end(); + + MethodOutput outputCall = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "call", SIG_ANYARRAY_ANY, null, null); + outputCall.start(); + definition.defineCall(outputCall); + outputCall.end(); + + MethodOutput outputAsBool = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "asBool", "()Z", null, null); + outputAsBool.start(); + definition.defineAsBool(outputAsBool); + outputAsBool.end(); + + MethodOutput outputAsByte = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "asByte", "()B", null, null); + outputAsByte.start(); + definition.defineAsByte(outputAsByte); + outputAsByte.end(); + + MethodOutput outputAsShort = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "asShort", "()S", null, null); + outputAsShort.start(); + definition.defineAsShort(outputAsShort); + outputAsShort.end(); + + MethodOutput outputAsInt = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "asInt", "()I", null, null); + outputAsInt.start(); + definition.defineAsInt(outputAsInt); + outputAsInt.end(); + + MethodOutput outputAsLong = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "asLong", "()J", null, null); + outputAsLong.start(); + definition.defineAsLong(outputAsLong); + outputAsLong.end(); + + MethodOutput outputAsFloat = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "asFloat", "()F", null, null); + outputAsFloat.start(); + definition.defineAsFloat(outputAsFloat); + outputAsFloat.end(); + + MethodOutput outputAsDouble = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "asDouble", "()D", null, null); + outputAsDouble.start(); + definition.defineAsDouble(outputAsDouble); + outputAsDouble.end(); + + MethodOutput outputAsString = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "asString", "()Ljava/lang/String;", null, null); + outputAsString.start(); + definition.defineAsString(outputAsString); + outputAsString.end(); + + MethodOutput outputAs = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "as", + "(Ljava/lang/Class;)" + signature(IAny.class), + "(Ljava/lang/Class;)TT;", + null); + outputAs.start(); + definition.defineAs(outputAs); + outputAs.end(); + + MethodOutput outputIs = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "is", + "(Ljava/lang/Class;)Z", + "(Ljava/lang/Class<*>;)Z", + null); + outputIs.start(); + definition.defineIs(outputIs); + outputIs.end(); + + MethodOutput outputCanCastImplicit = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "canCastImplicit", "(" + signature(Class.class) + ")Z", "(Ljava/lang/Class<*>;)Z", null); + outputCanCastImplicit.start(); + outputCanCastImplicit.loadObject(1); + outputCanCastImplicit.invokeStatic(name, "rtCanCastImplicit", "(Ljava/lang/Class;)Z"); + outputCanCastImplicit.returnInt(); + outputCanCastImplicit.end(); + + MethodOutput outputGetNumberType = new MethodOutput(writer, Opcodes.ACC_PUBLIC, "getNumberType", "()I", null, null); + outputGetNumberType.start(); + definition.defineGetNumberType(outputGetNumberType); + outputGetNumberType.end(); + + MethodOutput outputIteratorSingle = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "iteratorSingle", + "()" + signature(Iterator.class), + "()Ljava/util/Iterator;", + null); + outputIteratorSingle.start(); + definition.defineIteratorSingle(outputIteratorSingle); + outputIteratorSingle.end(); + + MethodOutput outputIteratorMulti = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "iteratorMulti", + "(I)Ljava/util/Iterator;", + "(I)Ljava/util/Iterator<[Lstanhebben/zenscript/value/IAny;>;", + null); + outputIteratorMulti.start(); + definition.defineIteratorMulti(outputIteratorMulti); + outputIteratorMulti.end(); + + MethodOutput outputHashCode = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "hashCode", + "()I", + null, + null); + outputHashCode.start(); + definition.defineHashCode(outputHashCode); + outputHashCode.end(); + + /*MethodOutput outputEquals = new MethodOutput( + writer, + Opcodes.ACC_PUBLIC, + "equals", + "(Ljava/lang/Object;)Z", + null, + null); + outputEquals.enableDebug(); + outputEquals.start(); + definition.defineEquals(outputEquals); + outputEquals.end();*/ + + writer.visitEnd(); + return writer.toByteArray(); + } catch (Exception ex) { + throw new RuntimeException("Could not construct any class for " + name, ex); + } } public static void throwUnsupportedException(MethodOutput output, String fromType, String operation) { diff --git a/ZenScript/src/main/java/stanhebben/zenscript/util/MethodOutput.java b/ZenScript/src/main/java/stanhebben/zenscript/util/MethodOutput.java index b1e96f0..7b69cb2 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/util/MethodOutput.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/util/MethodOutput.java @@ -7,6 +7,8 @@ package stanhebben.zenscript.util; import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; @@ -14,7 +16,6 @@ import org.objectweb.asm.Opcodes; import static org.objectweb.asm.Opcodes.*; import org.objectweb.asm.Type; import org.objectweb.asm.commons.LocalVariablesSorter; -import stanhebben.zenscript.type.natives.JavaMethod; import static stanhebben.zenscript.util.ZenTypeUtil.internal; import static stanhebben.zenscript.util.ZenTypeUtil.signature; @@ -23,8 +24,14 @@ import static stanhebben.zenscript.util.ZenTypeUtil.signature; * @author Stanneke */ public class MethodOutput { +// private static final boolean debug = true; + private final LocalVariablesSorter visitor; + private boolean debug = false; + private int labelIndex = 1; + private Map labelNames; + public MethodOutput(ClassVisitor cls, int access, String name, String descriptor, String signature, String[] exceptions) { MethodVisitor methodVisitor = cls.visitMethod(access, name, descriptor, signature, exceptions); visitor = new LocalVariablesSorter(access, descriptor, methodVisitor); @@ -34,16 +41,29 @@ public class MethodOutput { this.visitor = visitor; } + public void enableDebug() { + debug = true; + } + public void start() { + if (debug) + System.out.println("--start--"); + visitor.visitCode(); } public void end() { + if (debug) + System.out.println("--end--"); + visitor.visitMaxs(0, 0); visitor.visitEnd(); } public void label(Label label) { + if (debug) + System.out.println("Label " + getLabelName(label)); + visitor.visitLabel(label); } @@ -56,102 +76,177 @@ public class MethodOutput { } public void iConst0() { + if (debug) + System.out.println("iconst0"); + visitor.visitInsn(ICONST_0); } public void iConst1() { + if (debug) + System.out.println("iconst1"); + visitor.visitInsn(ICONST_1); } public void biPush(byte value) { + if (debug) + System.out.println("bipush"); + visitor.visitIntInsn(BIPUSH, value); } public void siPush(short value) { + if (debug) + System.out.println("sipush"); + visitor.visitIntInsn(SIPUSH, value); } public void aConstNull() { + if (debug) + System.out.println("null"); + visitor.visitInsn(ACONST_NULL); } public void constant(Object value) { + if (debug) + System.out.println("ldc " + value); + visitor.visitLdcInsn(value); } public void pop() { + if (debug) + System.out.println("pop"); + visitor.visitInsn(POP); } public void pop(boolean large) { + if (debug) + System.out.println("pop"); + visitor.visitInsn(large ? POP2 : POP); } public void dup() { + if (debug) + System.out.println("dup"); + visitor.visitInsn(DUP); } public void dup(boolean large) { + if (debug) + System.out.println("dup"); + visitor.visitInsn(large ? DUP2 : DUP); } public void dup2() { + if (debug) + System.out.println("dup2"); + visitor.visitInsn(DUP2); } public void dupX1() { + if (debug) + System.out.println("dupx1"); + visitor.visitInsn(DUP_X1); } public void dupX2() { + if (debug) + System.out.println("dupx2"); + visitor.visitInsn(DUP_X2); } public void dup2X1() { + if (debug) + System.out.println("dup2_x1"); + visitor.visitInsn(DUP2_X1); } public void dup2X2() { + if (debug) + System.out.println("dup2_x2"); + visitor.visitInsn(DUP2_X2); } public void store(Type type, int local) { + if (debug) + System.out.println("store " + local); + visitor.visitVarInsn(type.getOpcode(ISTORE), local); } public void load(Type type, int local) { + if (debug) + System.out.println("load " + local); + visitor.visitVarInsn(type.getOpcode(ILOAD), local); } public void storeInt(int local) { + if (debug) + System.out.println("storeInt " + local); + visitor.visitVarInsn(ISTORE, local); } public void loadInt(int local) { + if (debug) + System.out.println("loadInt " + local); + visitor.visitVarInsn(ILOAD, local); } public void storeObject(int local) { + if (debug) + System.out.println("storeObject " + local); + visitor.visitVarInsn(ASTORE, local); } public void loadObject(int local) { + if (debug) + System.out.println("loadObject " + local); + visitor.visitVarInsn(ALOAD, local); } public void arrayLength() { + if (debug) + System.out.println("arrayLength"); + visitor.visitInsn(ARRAYLENGTH); } public void arrayLoad(Type type) { + if (debug) + System.out.println("arrayLoad"); + visitor.visitInsn(type.getOpcode(IALOAD)); } public void arrayStore(Type type) { + if (debug) + System.out.println("arrayStore"); + visitor.visitInsn(type.getOpcode(IASTORE)); } public void newArray(Type componentType) { + if (debug) + System.out.println("newArray"); + int sort = componentType.getSort(); if (sort == Type.METHOD) { throw new RuntimeException("Unsupported array type: " + componentType); @@ -175,244 +270,424 @@ public class MethodOutput { } public void newArray(Class componentType) { + if (debug) + System.out.println("newArray " + componentType.getName()); + visitor.visitTypeInsn(NEWARRAY, internal(componentType)); } public void checkCast(Class newClass) { + if (debug) + System.out.println("checkCast " + newClass.getName()); + visitor.visitTypeInsn(CHECKCAST, signature(newClass)); } public void checkCast(String newClass) { + if (debug) + System.out.println("checkCast " + newClass); + visitor.visitTypeInsn(CHECKCAST, newClass); } public void iNeg() { + if (debug) + System.out.println("iNeg"); + visitor.visitInsn(INEG); } public void iAdd() { + if (debug) + System.out.println("iAdd"); + visitor.visitInsn(IADD); } public void iSub() { + if (debug) + System.out.println("iSub"); + visitor.visitInsn(ISUB); } public void iMul() { + if (debug) + System.out.println("iMul"); + visitor.visitInsn(IMUL); } public void iDiv() { + if (debug) + System.out.println("iDiv"); + visitor.visitInsn(IDIV); } public void iRem() { + if (debug) + System.out.println("iRem"); + visitor.visitInsn(IREM); } public void iAnd() { + if (debug) + System.out.println("iAnd"); + visitor.visitInsn(IAND); } public void iOr() { + if (debug) + System.out.println("iOr"); + visitor.visitInsn(IOR); } public void iXor() { + if (debug) + System.out.println("iXor"); + visitor.visitInsn(IXOR); } public void iNot() { + if (debug) + System.out.println("iNot"); + visitor.visitInsn(ICONST_M1); visitor.visitInsn(IXOR); } public void iShr() { + if (debug) + System.out.println("iShr"); + visitor.visitInsn(ISHR); } public void iShl() { + if (debug) + System.out.println("iShl"); + visitor.visitInsn(ISHL); } public void lNeg() { + if (debug) + System.out.println("lNeg"); + visitor.visitInsn(LNEG); } public void lAdd() { + if (debug) + System.out.println("lAdd"); + visitor.visitInsn(LADD); } public void lSub() { + if (debug) + System.out.println("lSub"); + visitor.visitInsn(LSUB); } public void lMul() { + if (debug) + System.out.println("lMul"); + visitor.visitInsn(LMUL); } public void lDiv() { + if (debug) + System.out.println("lDiv"); + visitor.visitInsn(LDIV); } public void lRem() { + if (debug) + System.out.println("lRem"); + visitor.visitInsn(LREM); } public void lAnd() { + if (debug) + System.out.println("lAnd"); + visitor.visitInsn(LAND); } public void lOr() { + if (debug) + System.out.println("lOr"); + visitor.visitInsn(LOR); } public void lXor() { + if (debug) + System.out.println("lXor"); + visitor.visitInsn(LXOR); } public void lNot() { + if (debug) + System.out.println("lNot"); + constant((long) -1); lXor(); } public void lShr() { + if (debug) + System.out.println("lShr"); + visitor.visitInsn(LSHR); } public void lShl() { + if (debug) + System.out.println("lShl"); + visitor.visitInsn(LSHL); } public void fNeg() { + if (debug) + System.out.println("fNeg"); + visitor.visitInsn(FNEG); } public void fAdd() { + if (debug) + System.out.println("fAdd"); + visitor.visitInsn(FADD); } public void fSub() { + if (debug) + System.out.println("fSub"); + visitor.visitInsn(FSUB); } public void fMul() { + if (debug) + System.out.println("fMul"); + visitor.visitInsn(FMUL); } public void fDiv() { + if (debug) + System.out.println("fDiv"); + visitor.visitInsn(FDIV); } public void fRem() { + if (debug) + System.out.println("fRem"); + visitor.visitInsn(FREM); } public void dNeg() { + if (debug) + System.out.println("dNeg"); + visitor.visitInsn(DNEG); } public void dAdd() { + if (debug) + System.out.println("dAdd"); + visitor.visitInsn(DADD); } public void dSub() { + if (debug) + System.out.println("dSub"); + visitor.visitInsn(DSUB); } public void dMul() { + if (debug) + System.out.println("dMul"); + visitor.visitInsn(DMUL); } public void dDiv() { + if (debug) + System.out.println("dDiv"); + visitor.visitInsn(DDIV); } public void dRem() { + if (debug) + System.out.println("dRem"); + visitor.visitInsn(DREM); } public void iinc(int local) { + if (debug) + System.out.println("iinc " + local); + visitor.visitIincInsn(local, 1); } public void iinc(int local, int increment) { + if (debug) + System.out.println("iinc " + local + " + " + increment); + visitor.visitIincInsn(local, increment); } public void i2b() { + if (debug) + System.out.println("i2b"); + visitor.visitInsn(I2B); } public void i2s() { + if (debug) + System.out.println("i2s"); + visitor.visitInsn(I2S); } public void i2l() { + if (debug) + System.out.println("i2l"); + visitor.visitInsn(I2L); } public void i2f() { + if (debug) + System.out.println("i2f"); + visitor.visitInsn(I2F); } public void i2d() { + if (debug) + System.out.println("i2d"); + visitor.visitInsn(I2D); } public void l2i() { + if (debug) + System.out.println("l2i"); + visitor.visitInsn(L2I); } public void l2f() { + if (debug) + System.out.println("l2f"); + visitor.visitInsn(L2F); } public void l2d() { + if (debug) + System.out.println("l2d"); + visitor.visitInsn(L2D); } public void f2i() { + if (debug) + System.out.println("f2i"); + visitor.visitInsn(F2I); } public void f2l() { + if (debug) + System.out.println("f2l"); + visitor.visitInsn(F2L); } public void f2d() { + if (debug) + System.out.println("f2d"); + visitor.visitInsn(F2D); } public void d2i() { + if (debug) + System.out.println("d2i"); + visitor.visitInsn(D2I); } public void d2l() { + if (debug) + System.out.println("d2l"); + visitor.visitInsn(D2L); } public void d2f() { + if (debug) + System.out.println("d2f"); + visitor.visitInsn(D2F); } public void lCmp() { + if (debug) + System.out.println("lCmp"); + visitor.visitInsn(LCMP); } public void fCmp() { + if (debug) + System.out.println("fCmp"); + visitor.visitInsn(FCMPL); } public void dCmp() { + if (debug) + System.out.println("dCmp"); + visitor.visitInsn(DCMPL); } public void instanceOf(String clsName) { + if (debug) + System.out.println("instanceOf " + clsName); + visitor.visitTypeInsn(INSTANCEOF, clsName); } public void invokeStatic(String owner, String name, String descriptor) { + if (debug) + System.out.println("invokeStatic " + owner + '.' + name + descriptor); + if (owner == null) throw new IllegalArgumentException("owner cannot be null"); if (name == null) @@ -431,21 +706,17 @@ public class MethodOutput { } descriptor.append(')'); descriptor.append(result == null ? 'V' : signature(result)); + + if (debug) + System.out.println("invokeStatic " + internal(owner) + '.' + name + descriptor); + visitor.visitMethodInsn(INVOKESTATIC, internal(owner), name, descriptor.toString()); } - public void invokeStatic(JavaMethod method) { - StringBuilder descriptor = new StringBuilder(); - descriptor.append('('); - for (Class argument : method.getMethod().getParameterTypes()) { - descriptor.append(signature(argument)); - } - descriptor.append(')'); - descriptor.append(signature(method.getMethod().getReturnType())); - visitor.visitMethodInsn(INVOKESTATIC, internal(method.getOwner()), method.getMethod().getName(), descriptor.toString()); - } - public void invokeSpecial(String owner, String name, String descriptor) { + if (debug) + System.out.println("invokeSpecial " + owner + '.' + name + descriptor); + visitor.visitMethodInsn(INVOKESPECIAL, owner, name, descriptor); } @@ -457,23 +728,10 @@ public class MethodOutput { } } - public void invoke(JavaMethod method) { - if (method.getOwner().isInterface()) { - invokeInterface( - method.getOwner(), - method.getMethod().getName(), - method.getMethod().getReturnType(), - method.getMethod().getParameterTypes()); - } else { - invokeVirtual( - method.getOwner(), - method.getMethod().getName(), - method.getMethod().getReturnType(), - method.getMethod().getParameterTypes()); - } - } - public void invokeVirtual(String owner, String name, String descriptor) { + if (debug) + System.out.println("invokeVirtual " + owner + '.' + name + descriptor); + visitor.visitMethodInsn(INVOKEVIRTUAL, owner, name, descriptor); } @@ -485,10 +743,17 @@ public class MethodOutput { } descriptor.append(')'); descriptor.append(result == null ? 'V' : signature(result)); + + if (debug) + System.out.println("invokeVirtual " + owner + '.' + name + descriptor); + visitor.visitMethodInsn(INVOKEVIRTUAL, internal(owner), name, descriptor.toString()); } public void invokeInterface(String owner, String name, String descriptor) { + if (debug) + System.out.println("invokeInterface " + owner + '.' + name + descriptor); + visitor.visitMethodInsn(INVOKEINTERFACE, owner, name, descriptor); } @@ -500,14 +765,24 @@ public class MethodOutput { } descriptor.append(')'); descriptor.append(result == null ? 'V' : signature(result)); + + if (debug) + System.out.println("invokeInterface " + owner + '.' + name + descriptor); + visitor.visitMethodInsn(INVOKEINTERFACE, internal(owner), name, descriptor.toString()); } public void newObject(Class type) { + if (debug) + System.out.println("newObject " + type.getName()); + visitor.visitTypeInsn(NEW, internal(type)); } public void newObject(String type) { + if (debug) + System.out.println("newObject " + type); + visitor.visitTypeInsn(NEW, type); } @@ -518,6 +793,10 @@ public class MethodOutput { descriptor.append(signature(argument)); } descriptor.append(")V"); + + if (debug) + System.out.println("invokeSpecial " + internal(type) + "." + descriptor); + visitor.visitMethodInsn(INVOKESPECIAL, internal(type), "", descriptor.toString()); } @@ -528,10 +807,17 @@ public class MethodOutput { descriptor.append(argument); } descriptor.append(")V"); + + if (debug) + System.out.println("invokeSpecial " + type + "." + descriptor); + visitor.visitMethodInsn(INVOKESPECIAL, type, "", descriptor.toString()); } public void goTo(Label lbl) { + if (debug) + System.out.println("goTo " + getLabelName(lbl)); + visitor.visitJumpInsn(GOTO, lbl); } @@ -541,114 +827,198 @@ public class MethodOutput { * @param lbl target label */ public void ifEQ(Label lbl) { + if (debug) + System.out.println("ifEQ " + getLabelName(lbl)); + visitor.visitJumpInsn(IFEQ, lbl); } public void ifNE(Label lbl) { + if (debug) + System.out.println("ifNE " + getLabelName(lbl)); + visitor.visitJumpInsn(IFNE, lbl); } public void ifLT(Label lbl) { + if (debug) + System.out.println("ifLT " + getLabelName(lbl)); + visitor.visitJumpInsn(IFLT, lbl); } public void ifGT(Label lbl) { + if (debug) + System.out.println("ifGT " + getLabelName(lbl)); + visitor.visitJumpInsn(IFGT, lbl); } public void ifGE(Label lbl) { + if (debug) + System.out.println("ifGE " + getLabelName(lbl)); + visitor.visitJumpInsn(IFGE, lbl); } public void ifLE(Label lbl) { + if (debug) + System.out.println("ifLE " + getLabelName(lbl)); + visitor.visitJumpInsn(IFLE, lbl); } public void ifICmpLE(Label lbl) { + if (debug) + System.out.println("ifICmpLE " + getLabelName(lbl)); + visitor.visitJumpInsn(IF_ICMPLE, lbl); } public void ifICmpGE(Label lbl) { + if (debug) + System.out.println("ifICmpGE " + getLabelName(lbl)); + visitor.visitJumpInsn(IF_ICMPGE, lbl); } public void ifICmpEQ(Label lbl) { + if (debug) + System.out.println("ifICmpEQ " + getLabelName(lbl)); + visitor.visitJumpInsn(IF_ICMPEQ, lbl); } public void ifICmpNE(Label lbl) { + if (debug) + System.out.println("ifICmpNE " + getLabelName(lbl)); + visitor.visitJumpInsn(IF_ICMPNE, lbl); } public void ifICmpGT(Label lbl) { + if (debug) + System.out.println("ifICmpGT " + getLabelName(lbl)); + visitor.visitJumpInsn(IF_ICMPGT, lbl); } public void ifICmpLT(Label lbl) { + if (debug) + System.out.println("ifICmpLT " + getLabelName(lbl)); + visitor.visitJumpInsn(IF_ICMPLT, lbl); } public void ifACmpEq(Label lbl) { + if (debug) + System.out.println("ifICmpEQ " + getLabelName(lbl)); + visitor.visitJumpInsn(IF_ACMPEQ, lbl); } public void ifACmpNe(Label lbl) { + if (debug) + System.out.println("ifACmpNE " + getLabelName(lbl)); + visitor.visitJumpInsn(IF_ACMPNE, lbl); } public void ifNull(Label lbl) { + if (debug) + System.out.println("ifNull " + getLabelName(lbl)); + visitor.visitJumpInsn(IFNULL, lbl); } public void ifNonNull(Label lbl) { + if (debug) + System.out.println("ifNonNull " + getLabelName(lbl)); + visitor.visitJumpInsn(IFNONNULL, lbl); } public void ret() { + if (debug) + System.out.println("ret"); + visitor.visitInsn(RETURN); } public void returnType(Type type) { + if (debug) + System.out.println("return " + type.getDescriptor()); + visitor.visitInsn(type.getOpcode(IRETURN)); } public void returnInt() { + if (debug) + System.out.println("ireturn"); + visitor.visitInsn(IRETURN); } public void returnObject() { + if (debug) + System.out.println("areturn"); + visitor.visitInsn(ARETURN); } public void getField(String owner, String name, String descriptor) { + if (debug) + System.out.println("getField " + owner + '.' + name + ":" + descriptor); + visitor.visitFieldInsn(GETFIELD, owner, name, descriptor); } public void getField(Class owner, String name, Class descriptor) { + if (debug) + System.out.println("getField " + owner.getName() + '.' + name + ":" + descriptor.getName()); + visitor.visitFieldInsn(GETFIELD, internal(owner), name, signature(descriptor)); } public void putField(String owner, String name, String descriptor) { + if (debug) + System.out.println("putField " + owner + '.' + name + ":" + descriptor); + visitor.visitFieldInsn(PUTFIELD, owner, name, descriptor); } public void putField(Class owner, String name, Class descriptor) { + if (debug) + System.out.println("putField " + owner.getName() + '.' + name + ":" + descriptor.getName()); + visitor.visitFieldInsn(PUTFIELD, internal(owner), name, signature(descriptor)); } public void getStaticField(String owner, String name, String descriptor) { + if (debug) + System.out.println("getStatic " + owner + '.' + name + ":" + descriptor); + visitor.visitFieldInsn(GETSTATIC, owner, name, descriptor); } public void getStaticField(Class owner, Field field) { + if (debug) + System.out.println("getField " + owner.getName() + '.' + field.getName() + ":" + signature(field.getType())); + visitor.visitFieldInsn(GETSTATIC, internal(owner), field.getName(), signature(field.getType())); } public void putStaticField(String owner, String name, String descriptor) { + if (debug) + System.out.println("putStatic " + owner + '.' + name + ":" + descriptor); + visitor.visitFieldInsn(PUTSTATIC, owner, name, descriptor); } public void putStaticField(Class owner, Field field) { + if (debug) + System.out.println("putStatic " + owner.getName() + '.' + field.getName() + ":" + signature(field.getType())); + visitor.visitFieldInsn(PUTSTATIC, internal(owner), field.getName(), signature(field.getType())); } @@ -661,4 +1031,15 @@ public class MethodOutput { visitor.visitLabel(label); visitor.visitLineNumber(position.getLine(), label); } + + private String getLabelName(Label lbl) { + if (labelNames == null) + labelNames = new HashMap(); + + if (!labelNames.containsKey(lbl)) { + labelNames.put(lbl, "L" + labelIndex++); + } + + return labelNames.get(lbl); + } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/util/StringUtil.java b/ZenScript/src/main/java/stanhebben/zenscript/util/StringUtil.java index 28cf15e..c34357c 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/util/StringUtil.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/util/StringUtil.java @@ -9,7 +9,7 @@ package stanhebben.zenscript.util; import java.util.ArrayList; import java.util.List; import stanhebben.zenscript.expression.Expression; -import stanhebben.zenscript.type.natives.JavaMethod; +import stanhebben.zenscript.type.natives.IJavaMethod; /** * @@ -54,7 +54,7 @@ public class StringUtil { * @param arguments calling arguments * @return return value */ - public static String methodMatchingError(List methods, Expression... arguments) { + public static String methodMatchingError(List methods, Expression... arguments) { if (methods.isEmpty()) { return "no method with that name available"; } else {