diff --git a/ISBPL.java b/ISBPL.java index abfab9e..22c56f1 100644 --- a/ISBPL.java +++ b/ISBPL.java @@ -209,6 +209,11 @@ public class ISBPL { // Create type ISBPLType type = registerType(typename); + for(; !words[idx].equals("{"); idx++) { + ISBPLType t = getType(words[idx]); + if(!type.superTypes.contains(t)) + type.superTypes.add(t); + } AtomicInteger i = new AtomicInteger(idx); String[] words2 = readBlock(i, words, file); boolean definingMethods = false; @@ -504,6 +509,11 @@ public class ISBPL { stack.push(toISBPLString(types.get(((int) i.object)).name)); }; break; + case "typeid": + func = (stack) -> { + stack.push(new ISBPLObject(getType("int"), getType(toJavaString(stack.pop())).id)); + }; + break; case "gettype": func = (Stack stack) -> { ISBPLObject o = stack.pop(); @@ -966,6 +976,17 @@ public class ISBPL { addFunction(t, "=" + s, (stack1) -> t.varget(stack1.pop()).put(var, stack1.pop())); }; break; + case "defsuper": + func = (stack) -> { + ISBPLObject type = stack.pop(); + ISBPLObject otherType = stack.pop(); + type.checkType(getType("int")); + otherType.checkType(getType("int")); + ISBPLType t = types.get((int) type.object); + ISBPLType s = types.get((int) otherType.object); + t.superTypes.add(s); + }; + break; case "callmethod": func = (stack) -> { ISBPLObject obj = stack.pop(); @@ -1014,7 +1035,11 @@ public class ISBPL { case "mkinstance": func = (stack) -> { ISBPLObject type = stack.pop(); - stack.push(new ISBPLObject(types.get((int) type.toLong()), new Object())); + ISBPLType t = types.get((int) type.toLong()); + stack.push(new ISBPLObject(t, new Object())); + if(t.methods.containsKey("construct")) { + t.methods.get("construct").call(stack); + } }; break; default: @@ -1583,7 +1608,15 @@ public class ISBPL { } } words.add(word.toString()); - return words.toArray(new String[0]); + + ArrayList cleanWords = new ArrayList<>(); + for(int i = 0; i < words.size(); i++) { + if(!words.get(i).isEmpty()) { + cleanWords.add(words.get(i)); + } + } + + return cleanWords.toArray(new String[0]); } private String cleanCode(String code) { @@ -1795,24 +1828,33 @@ class ISBPLObject { } public void checkType(ISBPLType wanted) { - if(wanted.id != type.id) { - throw new ISBPLError("IncompatibleTypes", "Incompatible types: " + type.name + " - " + wanted.name); + Queue types = new LinkedList<>(); + types.add(type); + while (!types.isEmpty()) { + type = types.poll(); + types.addAll(type.superTypes); + if(type.id == wanted.id) { + return; + } } + throw new ISBPLError("IncompatibleTypes", "Incompatible types: " + type.name + " - " + wanted.name); } public void checkTypeMulti(ISBPLType... wanted) { - int f = -1; StringBuilder wantedNames = new StringBuilder(); for (int i = 0 ; i < wanted.length ; i++) { wantedNames.append(" ").append(wanted[i].name); - if(wanted[i].id == type.id) { - f = i; - break; + Queue types = new LinkedList<>(); + types.add(type); + while (!types.isEmpty()) { + type = types.poll(); + types.addAll(type.superTypes); + if(type.id == wanted[i].id) { + return; + } } } - if(f == -1) { - throw new ISBPLError("IncompatibleTypes", "Incompatible types: " + type.name + " - " + wantedNames.substring(1)); - } + throw new ISBPLError("IncompatibleTypes", "Incompatible types: " + type.name + " - " + wantedNames.substring(1)); } @Override diff --git a/std.isbpl b/std.isbpl index 7ded679..7cb363a 100644 --- a/std.isbpl +++ b/std.isbpl @@ -45,6 +45,7 @@ native mktype native mkinstance native getos native typename +native typeid native gettype native settype "try and do are keywords, not functions" # @@ -70,6 +71,7 @@ native fcall native deffunc native defmethod native deffield +native defsuper native delete "deletes all field values from an object" # native callmethod @@ -82,10 +84,14 @@ func ) { } func ! { dup } +"The TYPE_ prefix is deprecated, but will be kept for backwards compatibility." # "int must be registered first." # def TYPE_INT construct int { # "no fields needed" ; + construct { + pop 0 + } new { "int has the new method because all types are ints" # mkinstance @@ -99,9 +105,13 @@ def TYPE_DOUBLE "double" mktype =TYPE_DOUBLE def TYPE_NULL "null" mktype =TYPE_NULL native null def TYPE_FUNCTION "func" mktype =TYPE_FUNCTION +def Function TYPE_FUNCTION =Function def TYPE_ARRAY construct array { ; + construct { + pop anew + } foreach { def this =this def lambda =lambda @@ -109,9 +119,17 @@ def TYPE_ARRAY construct array { while { i this alen lt } { this i aget lambda fcall i ++ =i } } } =TYPE_ARRAY -def TYPE_STRING "string" mktype =TYPE_STRING +def Array TYPE_ARRAY =Array +def TYPE_STRING construct string array { + ; + _array { + Array settype + } +} =TYPE_STRING +def String TYPE_STRING =String def TYPE_JIO construct jio { + jioclass ; class { pop