Skip to content

Commit

Permalink
Correction du mangling sur certains types composés.
Browse files Browse the repository at this point in the history
Ajout de fonctions pour Map.
  • Loading branch information
Enalye committed Sep 29, 2021
1 parent 2e53264 commit 121f80d
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 48 deletions.
61 changes: 21 additions & 40 deletions source/grimoire/compiler/mangle.d
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,9 @@ GrType[] grUnmangleSignature(string mangledSignature) {
int i;
while (i < mangledSignature.length) {
//Type separator
if (mangledSignature[i] != '$')
if (mangledSignature[i] != '$') {
throw new Exception("Invalid unmangle signature mangling format, missing $");
}
i++;

//Value
Expand All @@ -107,7 +108,7 @@ GrType[] grUnmangleSignature(string mangledSignature) {
case 'n':
i++;
currentType.baseType = GrBaseType.array_;
currentType.mangledType = grUnmangleSubFunction(mangledSignature, i);
currentType.mangledType = grUnmangleBlock(mangledSignature, i);
break;
case 'e':
currentType.baseType = GrBaseType.enum_;
Expand All @@ -128,54 +129,34 @@ GrType[] grUnmangleSignature(string mangledSignature) {
break;
case 'p':
currentType.baseType = GrBaseType.class_;
string structName;
if ((i + 2) >= mangledSignature.length)
throw new Exception("Invalid mangling format");
i++;
if (mangledSignature[i] != '(')
throw new Exception("Invalid mangling format");
i++;
while (mangledSignature[i] != ')') {
structName ~= mangledSignature[i];
i++;
if (i >= mangledSignature.length)
throw new Exception("Invalid mangling format");
}
currentType.mangledType = structName;
currentType.mangledType = grUnmangleBlock(mangledSignature, i);
break;
case 'u':
currentType.baseType = GrBaseType.foreign;
string foreignName;
if ((i + 2) >= mangledSignature.length)
throw new Exception("Invalid mangling format");
i++;
if (mangledSignature[i] != '(')
throw new Exception("Invalid mangling format");
i++;
while (mangledSignature[i] != ')') {
foreignName ~= mangledSignature[i];
i++;
if (i >= mangledSignature.length)
throw new Exception("Invalid mangling format");
}
currentType.mangledType = foreignName;
currentType.mangledType = grUnmangleBlock(mangledSignature, i);
break;
case 'f':
i++;
currentType.baseType = GrBaseType.function_;
currentType.mangledType = grUnmangleSubFunction(mangledSignature, i);
currentType.mangledType = grUnmangleBlock(mangledSignature, i);
i++;
currentType.mangledReturnType = grUnmangleSubFunction(mangledSignature, i);
currentType.mangledReturnType = grUnmangleBlock(mangledSignature, i);
break;
case 't':
i++;
currentType.baseType = GrBaseType.task;
currentType.mangledType = grUnmangleSubFunction(mangledSignature, i);
currentType.mangledType = grUnmangleBlock(mangledSignature, i);
break;
case 'c':
i++;
currentType.baseType = GrBaseType.chan;
currentType.mangledType = grUnmangleSubFunction(mangledSignature, i);
currentType.mangledType = grUnmangleBlock(mangledSignature, i);
break;
default:
break;
Expand Down Expand Up @@ -204,28 +185,28 @@ string grMangleComposite(string name, GrType[] signature) {

/// Reverses the grMangleComposite operation.
/// Returns a struct containing the name and the signature.
auto grUnmangleComposite(string mangledSignature) {
auto grUnmangleComposite(string mangledSignature) {
struct UnmangleCompositeResult {
string name;
GrType[] signature;
}

UnmangleCompositeResult result;
size_t index = mangledSignature.indexOf('$');
if(index == -1) {
if (index == -1) {
result.name = mangledSignature;
return result;
}
result.name = mangledSignature[0..index];
result.signature = grUnmangleSignature(mangledSignature[index..$]);
result.name = mangledSignature[0 .. index];
result.signature = grUnmangleSignature(mangledSignature[index .. $]);
return result;
}

/// Reverse the mangling operation for a function passed as a parameter.
string grUnmangleSubFunction(string mangledSignature, ref int i) {
string grUnmangleBlock(string mangledSignature, ref int i) {
string subString;
int blockCount = 1;
if (i >= mangledSignature.length && mangledSignature[i] != '(')
if (i >= mangledSignature.length || mangledSignature[i] != '(')
throw new Exception("Invalid subType mangling format, missing (");
i++;

Expand Down Expand Up @@ -279,7 +260,7 @@ GrType grUnmangle(string mangledSignature) {
case 'n':
i++;
currentType.baseType = GrBaseType.array_;
currentType.mangledType = grUnmangleSubFunction(mangledSignature, i);
currentType.mangledType = grUnmangleBlock(mangledSignature, i);
i++;
break;
case 'e':
Expand Down Expand Up @@ -336,21 +317,21 @@ GrType grUnmangle(string mangledSignature) {
case 'f':
i++;
currentType.baseType = GrBaseType.function_;
currentType.mangledType = grUnmangleSubFunction(mangledSignature, i);
currentType.mangledType = grUnmangleBlock(mangledSignature, i);
i++;
currentType.mangledReturnType = grUnmangleSubFunction(mangledSignature, i);
currentType.mangledReturnType = grUnmangleBlock(mangledSignature, i);
i++;
break;
case 't':
i++;
currentType.baseType = GrBaseType.task;
currentType.mangledType = grUnmangleSubFunction(mangledSignature, i);
currentType.mangledType = grUnmangleBlock(mangledSignature, i);
i++;
break;
case 'c':
i++;
currentType.baseType = GrBaseType.chan;
currentType.mangledType = grUnmangleSubFunction(mangledSignature, i);
currentType.mangledType = grUnmangleBlock(mangledSignature, i);
i++;
break;
default:
Expand All @@ -359,4 +340,4 @@ GrType grUnmangle(string mangledSignature) {
}

return currentType;
}
}
168 changes: 160 additions & 8 deletions source/grimoire/stdlib/map.d
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
module grimoire.stdlib.map;

import std.typecons : Tuple, tuple;

import std.conv : to;
import grimoire.assembly, grimoire.compiler, grimoire.runtime;
import grimoire.stdlib.util;

/// Hashmap
private final class Map(T) {
Expand All @@ -20,6 +21,10 @@ private final class Map(T) {
data[keys[i]] = values[i];
}
}

this(Map!T map) {
data = map.data.dup;
}
}

private {
Expand Down Expand Up @@ -65,6 +70,20 @@ package(grimoire.stdlib) void grLoadStdLibMap(GrLibrary library) {
library.addPrimitive(&_make_!\"" ~ t
~ "\", \"Map\", [grStringArray, any" ~ t ~ "Array], [grAny(\"M\")]);
library.addPrimitive(&_copy_!\"" ~ t
~ "\", \"copy\", [any" ~ t ~ "Map], [grAny(\"M\")]);
library.addPrimitive(&_size_!\"" ~ t ~ "\", \"size\", [any"
~ t ~ "Map], [grInt]);
library.addPrimitive(&_empty_!\"" ~ t ~ "\", \"empty?\", [
any" ~ t ~ "Map
], [grBool]);
library.addPrimitive(&_clear_!\"" ~ t ~ "\", \"clear\", [
any" ~ t ~ "Map
], [grAny(\"M\")]);
library.addPrimitive(&_set_!\"" ~ t
~ "\", \"set\", [any" ~ t ~ "Map, grString, grAny(\"T\")]);
Expand All @@ -77,13 +96,13 @@ package(grimoire.stdlib) void grLoadStdLibMap(GrLibrary library) {
library.addPrimitive(&_remove_!\"" ~ t
~ "\", \"remove\", [any" ~ t ~ "Map, grString]);
library.addPrimitive(&_byKeys_!\"" ~ t ~ "\", \"byKeys\", [any"
~ t ~ "Map], [grStringArray]);
library.addPrimitive(&_byKeys_!\"" ~ t ~ "\", \"byKeys\", [any" ~ t
~ "Map], [grStringArray]);
library.addPrimitive(&_byValues_!\"" ~ t ~ "\", \"byValues\", [any" ~ t ~ "Map], [any" ~ t ~ "Array]);
library.addPrimitive(&_byValues_!\"" ~ t ~ "\", \"byValues\", [any" ~ t ~ "Map], [any"
~ t ~ "Array]);
library.addPrimitive(&_each_!\""
~ t ~ "\", \"each\", [
library.addPrimitive(&_each_!\"" ~ t ~ "\", \"each\", [
grAny(\"A\", (type, data) {
if (type.baseType != GrBaseType.foreign)
return false;
Expand Down Expand Up @@ -111,14 +130,67 @@ package(grimoire.stdlib) void grLoadStdLibMap(GrLibrary library) {
], [grBool, grAny(\"T\")]);
");
}

GrType boolMap = grGetForeignType("Map", [grBool]);
library.addPrimitive(&_print_!("bool", false), "print", [boolMap]);
library.addPrimitive(&_print_!("bool", true), "printl", [boolMap]);

GrType intMap = grGetForeignType("Map", [grInt]);
library.addPrimitive(&_print_!("int", false), "print", [intMap]);
library.addPrimitive(&_print_!("int", true), "printl", [intMap]);

GrType floatMap = grGetForeignType("Map", [grFloat]);
library.addPrimitive(&_print_!("float", false), "print", [floatMap]);
library.addPrimitive(&_print_!("float", true), "printl", [floatMap]);

GrType stringMap = grGetForeignType("Map", [grString]);
library.addPrimitive(&_print_!("string", false), "print", [stringMap]);
library.addPrimitive(&_print_!("string", true), "printl", [stringMap]);
}

private void _make_(string t)(GrCall call) {
mixin(t ~ "Map map = new " ~ t ~ "Map(call.getStringArray(0).data, call.get" ~ t
~ "Array(1).data);");
mixin(t ~ "Map map = new " ~ t ~ "Map(call.getStringArray(0).data, call.get"
~ t ~ "Array(1).data);");
call.setForeign(map);
}

private void _copy_(string t)(GrCall call) {
mixin(t ~ "Map map = call.getForeign!" ~ t ~ "Map(0);");
if (!map) {
call.raise("NullError");
return;
}
mixin("call.setForeign!" ~ t ~ "Map(new " ~ t ~ "Map(map));");
}

private void _size_(string t)(GrCall call) {
mixin(t ~ "Map map = call.getForeign!" ~ t ~ "Map(0);");
if (!map) {
call.raise("NullError");
return;
}
call.setInt(cast(GrInt) map.data.length);
}

private void _empty_(string t)(GrCall call) {
mixin("const " ~ t ~ "Map map = call.getForeign!" ~ t ~ "Map(0);");
if (!map) {
call.raise("NullError");
return;
}
call.setBool(map.data.length == 0);
}

private void _clear_(string t)(GrCall call) {
mixin(t ~ "Map map = call.getForeign!" ~ t ~ "Map(0);");
if (!map) {
call.raise("NullError");
return;
}
map.data.clear();
mixin("call.setForeign!" ~ t ~ "Map(map);");
}

private void _set_(string t)(GrCall call) {
mixin(t ~ "Map map = call.getForeign!(" ~ t ~ "Map)(0);");
if (!map) {
Expand Down Expand Up @@ -187,6 +259,48 @@ private void _byValues_(string t)(GrCall call) {
mixin("call.set" ~ t ~ "Array(ary);");
}

private void _printb_(string t)(GrCall call) {
Map map = call.getForeign!(IntMap)(0);
if (!map) {
call.raise("NullError");
return;
}
GrString result = "{";
bool isFirst = true;
foreach (key, value; map.data) {
if (isFirst) {
isFirst = false;
}
else {
result ~= ", ";
}
result ~= "\"" ~ key ~ "\"=>" ~ to!string(cast(GrBool) value);
}
result ~= "}";
_stdOut(result);
}

private void _printlb_(string t)(GrCall call) {
Map map = call.getForeign!(IntMap)(0);
if (!map) {
call.raise("NullError");
return;
}
GrString result = "{";
bool isFirst = true;
foreach (key, value; map.data) {
if (isFirst) {
isFirst = false;
}
else {
result ~= ", ";
}
result ~= "\"" ~ key ~ "\"=>" ~ to!string(cast(GrBool) value);
}
result ~= "}\n";
_stdOut(result);
}

private void _each_(string t)(GrCall call) {
mixin(t ~ "Map map = call.getForeign!(" ~ t ~ "Map)(0);");
if (!map) {
Expand Down Expand Up @@ -260,3 +374,41 @@ private void _next_(string t)(GrCall call) {
}
iter.index++;
}

private void _print_(string t, bool newLine)(GrCall call) {
static if (t == "bool" || t == "int") {
IntMap map = call.getForeign!(IntMap)(0);
}
else static if (t == "float") {
FloatMap map = call.getForeign!(FloatMap)(0);
}
else static if (t == "string") {
StringMap map = call.getForeign!(StringMap)(0);
}
if (!map) {
call.raise("NullError");
return;
}
GrString result = "{";
bool isFirst = true;
foreach (key, value; map.data) {
if (isFirst) {
isFirst = false;
}
else {
result ~= ", ";
}
result ~= "\"" ~ key ~ "\"=>";
static if (t == "string") {
result ~= "\"" ~ to!string(value) ~ "\"";
}
else static if (t == "bool") {
result ~= to!string(cast(bool) value);
}
else {
result ~= to!string(value);
}
}
result ~= newLine ? "}\n" : "}";
_stdOut(result);
}

0 comments on commit 121f80d

Please sign in to comment.