Skip to content

Commit

Permalink
Add various improvements and refactors
Browse files Browse the repository at this point in the history
  • Loading branch information
dkorpel committed Aug 12, 2023
1 parent 5f1cb19 commit 6db3abf
Show file tree
Hide file tree
Showing 6 changed files with 353 additions and 456 deletions.
107 changes: 28 additions & 79 deletions source/ctod/cdeclaration.d
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ nothrow @safe:
import ctod.tree_sitter;
import ctod.translate;
import ctod.ctype;
// import bops.tostring: toGcString;

/// Returns: true if a declaration was matched and replaced
bool ctodTryDeclaration(ref CtodCtx ctx, ref Node node) {
Decl[] ctodTryDeclaration(ref CtodCtx ctx, ref Node node) {
InlineType[] inlinetypes;

bool translateDecl(string suffix, bool cInit) {
Decl[] translateDecl(string suffix, bool cInit) {
string apiMacro;
Decl[] decls = parseDecls(ctx, node, inlinetypes, &apiMacro);

Expand Down Expand Up @@ -47,7 +46,8 @@ bool ctodTryDeclaration(ref CtodCtx ctx, ref Node node) {
}
result ~= suffix;
node.replace(result);
return true;
node.isTranslated = true;
return decls;
}

switch(node.typeEnum) {
Expand Down Expand Up @@ -95,7 +95,17 @@ bool ctodTryDeclaration(ref CtodCtx ctx, ref Node node) {
}
}
node.replace(result);
return true;
return decls;
default:
break;
}
return null;
}

/// Try translating variable initializers
/// Returns: true if translation is done, no need to translate children
bool ctodTryInitializer(ref CtodCtx ctx, ref Node node) {
switch(node.typeEnum) {
case Sym.compound_literal_expression:
// (Rectangle){x, y, width, height} => Rectangle(x, y, width, height)
foreach(ref c; node.children) {
Expand Down Expand Up @@ -165,7 +175,7 @@ bool ctodTryDeclaration(ref CtodCtx ctx, ref Node node) {
node.append(":");
break;
case Sym.subscript_designator:
// [a] = b => a: b, this removes the [] and adds :
// [a] = b => a: b
if (auto c = node.firstChildType(Sym.anon_LBRACK)) {
c.replace("");
}
Expand All @@ -174,88 +184,27 @@ bool ctodTryDeclaration(ref CtodCtx ctx, ref Node node) {
}
node.append(":");
break;
default: break;
default:
break;
}
return false;
}

/// Modify C identifiers that are keywords in D
string translateIdentifier(string s) {
return mapLookup(keyWordMap, s, s);
return mapLookup(keyWordMap, s, null) ? s ~ "_" : s;
}

/// C identifiers that are keywords in D
/// Does not include keywords that are in both C and D (if, switch, static)
/// or have similar meaning (null, true, assert)
private immutable string[2][] keyWordMap = [
["abstract", "abstract_"],
["alias", "alias_"],
["align", "align_"],
["asm", "asm_"],
["auto", "auto_"],
["bool", "bool_"],
["byte", "byte_"],
["cast", "cast_"],
["catch", "catch_"],
["cdouble", "cdouble_"],
["cent", "cent_"],
["cfloat", "cfloat_"],
["char", "char_"],
["class", "class_"],
["creal", "creal_"],
["dchar", "dchar_"],
["debug", "debug_"],
["delegate", "delegate_"],
["deprecated", "deprecated_"],
["export", "export_"],
["final", "final_"],
["finally", "finally_"],
["foreach", "foreach_"],
["foreach_reverse", "foreach_reverse_"],
["function", "function_"],
["idouble", "idouble_"],
["ifloat", "ifloat_"],
["immutable", "immutable_"],
["import", "import_"],
["in", "in_"],
["inout", "inout_"],
["interface", "interface_"],
["invariant", "invariant_"],
["ireal", "ireal_"],
["is", "is_"],
["lazy", "lazy_"],
["macro", "macro_"],
["mixin", "mixin_"],
["module", "module_"],
["new", "new_"],
["nothrow", "nothrow_"],
["out", "out_"],
["override", "override_"],
["package", "package_"],
["pragma", "pragma_"],
["private", "private_"],
["protected", "protected_"],
["public", "public_"],
["pure", "pure_"],
["real", "real_"],
["ref", "ref_"],
["scope", "scope_"],
["shared", "shared_"],
["super", "super_"],
["synchronized", "synchronized_"],
["template", "template_"],
["this", "this_"],
["throw", "throw_"],
["try", "try_"],
["typeid", "typeid_"],
["typeof", "typeof_"],
["ubyte", "ubyte_"],
["ucent", "ucent_"],
["uint", "uint_"],
["ulong", "ulong_"],
["unittest", "unittest_"],
["ushort", "ushort_"],
["version", "version_"],
["wchar", "wchar_"],
["with", "with_"],
private immutable string[] keyWordMap = [
"abstract", "alias", "align", "asm", "auto", "bool", "byte", "cast", "catch", "cdouble",
"cent", "cfloat", "char", "class", "creal", "dchar", "debug", "delegate", "deprecated",
"export", "final", "finally", "foreach", "foreach_reverse", "function", "idouble", "ifloat",
"immutable", "import", "in", "inout", "interface", "invariant", "ireal", "is", "lazy", "macro",
"mixin", "module", "new", "nothrow", "out", "override", "package", "pragma", "private",
"protected", "public", "pure", "real", "ref", "scope", "shared", "super", "synchronized",
"template", "this", "throw", "try", "typeid", "typeof", "ubyte", "ucent", "uint", "ulong",
"unittest", "ushort", "version", "wchar", "with",
];
70 changes: 67 additions & 3 deletions source/ctod/cexpr.d
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Node* getParenContent(return scope Node* node) {
if (node.typeEnum != Sym.parenthesized_expression && node.typeEnum != Sym.parenthesized_declarator) {
return node;
}
foreach(i; 1..node.children.length + -1) {
foreach(i; 1 .. node.children.length + -1) {
if (node.children[i].typeEnum != Sym.comment) {
return &node.children[i];
}
Expand All @@ -27,8 +27,7 @@ Node* getParenContent(return scope Node* node) {
/// WIP: type check as well
/// Things to be done:
/// - implicit casts from int to short, char, etc. must be explicit in D
/// - pointer casts (other than void*) must be explicit in D
/// - pointer arithmetic on static arrays can only be done after .ptr
/// - pointer arithmetic on static arrays can only be done after adding `.ptr`
bool ctodExpression(ref CtodCtx ctx, ref Node node) {
void depthFirst() {
foreach(ref c; node.children) {
Expand All @@ -43,6 +42,13 @@ bool ctodExpression(ref CtodCtx ctx, ref Node node) {
if (string s = translateIdentifier(node.source)) {
node.replace(s);
}
if (string limit = mapLookup(limitMap, node.source, null)) {
node.replace(limit);
}
if (node.source in ctx.macroFuncParams) {
node.prepend("` ~ ");
node.append(" ~ `");
}
if (Decl decl = ctx.lookupDecl(node.source)) {
ctx.setExpType(node, decl.type);
} else {
Expand Down Expand Up @@ -176,6 +182,7 @@ bool ctodExpression(ref CtodCtx ctx, ref Node node) {
ctx.setExpType(node, CType.unknown);
break;
case Sym.call_expression:
bool isMacroFunc = false;
if (auto funcNode = node.childField(Field.function_)) {
CType fType = ctx.expType(*funcNode);
if (fType.isFunction) {
Expand All @@ -201,12 +208,36 @@ bool ctodExpression(ref CtodCtx ctx, ref Node node) {
return true;
}
}

// SQR(...) => mixin(SQR!(...))
if (auto mcro = funcNode.source in ctx.macroTable) {
if (*mcro == MacroType.inlineFunc) {
funcNode.append("!");
if (ctx.inMacroFunction) {
node.prepend("` ~ ");
node.append(" ~ `");
} else {
node.prepend("mixin(");
node.append(")");
}
isMacroFunc = true;
}
}
}
if (auto argsNode = node.childField(Field.arguments)) {
if (argsNode.typeEnum != Sym.argument_list) {
break;
}
foreach(ref c; argsNode.children) {
if (c.typeEnum == Sym.anon_COMMA || c.typeEnum == Sym.comment ||
c.typeEnum == Sym.anon_LPAREN || c.typeEnum == Sym.anon_RPAREN) {
continue;
}
if (isMacroFunc) {
c.prepend("`");
c.append("`");
continue;
}
if (c.typeEnum != Sym.identifier) {
continue;
}
Expand Down Expand Up @@ -252,6 +283,9 @@ void convertPointerTypes(ref CtodCtx ctx, CType lType, ref Node r) {
if (lType.next[0] == CType.named("void")) {
return; // D can implicitly convert to `void*`
}
if (rType.next[0] == CType.named("noreturn")) {
return; // `null` can convert to any pointer type
}
if (rType == CType.stringLiteral) {
// This might be because of const mismatch,
// we don't want to simply cast away const with D string literals
Expand Down Expand Up @@ -377,3 +411,33 @@ private bool ctodSizeof(ref CtodCtx ctx, ref Node node) {
}
return false;
}

private immutable string[2][] limitMap = [
["DBL_DIG", "double.dig"],
["DBL_EPSILON", "double.epsilon"],
["DBL_MANT_DIG", "double.mant_dig"],
["DBL_MAX_10_EXP", "double.max_10_exp"],
["DBL_MAX_EXP", "double.max_exp"],
["DBL_MAX", "double.max"],
["DBL_MIN_10_EXP", "double.min_10_exp"],
["DBL_MIN_EXP", "double.min_exp"],
["DBL_MIN", "double.min"],
["FLT_DIG", "float.dig"],
["FLT_EPSILON", "float.epsilon"],
["FLT_MANT_DIG", "float.mant_dig"],
["FLT_MAX_10_EXP", "float.max_10_exp"],
["FLT_MAX_EXP", "float.max_exp"],
["FLT_MAX", "float.max"],
["FLT_MIN_10_EXP", "float.min_10_exp"],
["FLT_MIN_EXP", "float.min_exp"],
["FLT_MIN", "float.min"],
["LDBL_DIG", "real.dig"],
["LDBL_EPSILON", "real.epsilon"],
["LDBL_MANT_DIG", "real.mant_dig"],
["LDBL_MAX_10_EXP", "real.max_10_exp"],
["LDBL_MAX_EXP", "real.max_exp"],
["LDBL_MAX", "real.max"],
["LDBL_MIN_10_EXP", "real.min_10_exp"],
["LDBL_MIN_EXP", "real.min_exp"],
["LDBL_MIN", "real.min"],
];
Loading

0 comments on commit 6db3abf

Please sign in to comment.