Skip to content

Commit

Permalink
[d] New backend.
Browse files Browse the repository at this point in the history
  • Loading branch information
epi committed Mar 10, 2023
1 parent 0693f3b commit 2170d65
Show file tree
Hide file tree
Showing 20 changed files with 1,767 additions and 104 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ jobs:
dotnet-version: 6.0.406
- uses: actions/checkout@main
- run: make -j3 test-cs
d:
runs-on: ubuntu-22.04
steps:
- uses: dlang-community/setup-dlang@v1
with:
compiler: dmd-latest
- uses: actions/checkout@main
- run: make -j3 test-d
js-ts:
runs-on: ubuntu-22.04
steps:
Expand Down
5 changes: 5 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ jobs:
script: make -j5 test-cpp test-java CXX='clang++-12 -std=c++20'
- name: cs
script: make -j5 test-cs
- name: d
install:
- curl -fsS https://dlang.org/install.sh -O
- bash install.sh
script: source `bash install.sh -a` && make -j5 test-d
- name: js, ts
install: nvm install node
script: make -j5 test-js test-ts
Expand Down
2 changes: 2 additions & 0 deletions CiTo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ static void Usage()
Console.WriteLine("-l c Translate to C");
Console.WriteLine("-l cpp Translate to C++");
Console.WriteLine("-l cs Translate to C#");
Console.WriteLine("-l d Translate to D");
Console.WriteLine("-l java Translate to Java");
Console.WriteLine("-l js Translate to JavaScript");
Console.WriteLine("-l py Translate to Python");
Expand Down Expand Up @@ -76,6 +77,7 @@ static bool Emit(CiProgram program, string lang, string namespace_, string outpu
case "c": gen = new GenC(); break;
case "cpp": gen = new GenCpp(); break;
case "cs": gen = new GenCs(); break;
case "d": gen = new GenD(); break;
case "java": gen = new GenJava(); break;
case "js": case "mjs": gen = new GenJs(); break;
case "py": gen = new GenPy(); break;
Expand Down
11 changes: 8 additions & 3 deletions GenBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,17 @@ protected TypeCode GetTypeCode(CiType type, bool promote)
}
}

protected bool WriteRegexOptions(List<CiExpr> args, string prefix, string separator, string suffix, string i, string m, string s)
protected RegexOptions GetRegexOptions(List<CiExpr> args)
{
CiExpr expr = args[args.Count - 1];
if (!(expr.Type is CiEnum))
return false;
RegexOptions options = (RegexOptions) expr.IntValue();
return RegexOptions.None;
return (RegexOptions) expr.IntValue();
}

protected bool WriteRegexOptions(List<CiExpr> args, string prefix, string separator, string suffix, string i, string m, string s)
{
RegexOptions options = GetRegexOptions(args);
if (options == RegexOptions.None)
return false;
Write(prefix);
Expand Down
19 changes: 13 additions & 6 deletions GenBaseBase.ci
Original file line number Diff line number Diff line change
Expand Up @@ -1425,16 +1425,23 @@ public abstract class GenBaseBase : CiExprVisitor
}
}

protected void WriteSwitchWhenVars!(CiSwitch statement)
protected void DefineVar!(CiVar def)
{
if (def.Name != "_") {
WriteVar(def);
EndStatement();
}
}

protected void WriteSwitchWhenVars!(CiSwitch statement, bool whenOnly = true)
{
foreach (CiCase kase in statement.Cases) {
foreach (CiExpr value in kase.Values) {
if (value is CiBinaryExpr when1 && when1.Op == CiToken.When) {
if (!whenOnly && value is CiVar var)
DefineVar(var);
else if (value is CiBinaryExpr when1 && when1.Op == CiToken.When) {
assert when1.Left is CiVar whenVar;
if (whenVar.Name != "_") {
WriteVar(whenVar);
EndStatement();
}
DefineVar(whenVar);
WriteTemporaries(when1);
}
}
Expand Down
70 changes: 1 addition & 69 deletions GenCCpp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@
namespace Foxoft.Ci
{

public abstract class GenCCpp : GenTyped
public abstract class GenCCpp : GenCCppD
{
protected readonly List<CiSwitch> SwitchesWithGoto = new List<CiSwitch>();

protected abstract void IncludeStdInt();

protected abstract void IncludeAssert();
Expand Down Expand Up @@ -189,12 +187,6 @@ protected void WriteStringLiteralWithNewLine(string s)
Write("\\n\"");
}

public override void VisitConst(CiConst statement)
{
if (statement.Type is CiArrayStorageType)
WriteConst(statement);
}

protected virtual void WriteUnreachable(CiAssert statement)
{
// TODO: C23, C++23: unreachable()
Expand Down Expand Up @@ -224,66 +216,6 @@ protected override void WriteAssert(CiAssert statement)
WriteUnreachable(statement);
}

public override void VisitBreak(CiBreak statement)
{
if (statement.LoopOrSwitch is CiSwitch switchStatement) {
int gotoId = this.SwitchesWithGoto.IndexOf(switchStatement);
if (gotoId >= 0) {
Write("goto ciafterswitch");
VisitLiteralLong(gotoId);
WriteCharLine(';');
return;
}
}
base.VisitBreak(statement);
}

protected int GetSwitchGoto(CiSwitch statement)
{
if (statement.Cases.Any(kase => CiSwitch.HasEarlyBreakAndContinue(kase.Body))
|| CiSwitch.HasEarlyBreakAndContinue(statement.DefaultBody)) {
this.SwitchesWithGoto.Add(statement);
return this.SwitchesWithGoto.Count - 1;
}
return -1;
}

protected void WriteIfCaseBody(List<CiStatement> body, bool doWhile)
{
int length = CiSwitch.LengthWithoutTrailingBreak(body);
if (doWhile && CiSwitch.HasEarlyBreak(body)) {
this.Indent++;
WriteNewLine();
Write("do ");
OpenBlock();
WriteFirstStatements(body, length);
CloseBlock();
WriteLine("while (0);");
this.Indent--;
}
else if (length == 1)
WriteChild(body[0]);
else {
WriteChar(' ');
OpenBlock();
WriteFirstStatements(body, length);
CloseBlock();
}
}

protected void EndSwitchAsIfs(CiSwitch statement, int gotoId)
{
if (statement.HasDefault()) {
Write("else");
WriteIfCaseBody(statement.DefaultBody, gotoId < 0);
}
if (gotoId >= 0) {
Write("ciafterswitch");
VisitLiteralLong(gotoId);
WriteLine(": ;");
}
}

public override void VisitSwitch(CiSwitch statement)
{
if (!(statement.Value.Type is CiStringType)) {
Expand Down
101 changes: 101 additions & 0 deletions GenCCppD.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// GenCCppD.cs - Base for C/C++/D code generators
//
// Copyright (C) 2011-2023 Piotr Fusik
//
// This file is part of CiTo, see https://github.com/pfusik/cito
//
// CiTo is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// CiTo is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with CiTo. If not, see http://www.gnu.org/licenses/

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Foxoft.Ci
{

public abstract class GenCCppD : GenTyped
{
protected readonly List<CiSwitch> SwitchesWithGoto = new List<CiSwitch>();

public override void VisitConst(CiConst statement)
{
if (statement.Type is CiArrayStorageType)
WriteConst(statement);
}

public override void VisitBreak(CiBreak statement)
{
if (statement.LoopOrSwitch is CiSwitch switchStatement) {
int gotoId = this.SwitchesWithGoto.IndexOf(switchStatement);
if (gotoId >= 0) {
Write("goto ciafterswitch");
VisitLiteralLong(gotoId);
WriteCharLine(';');
return;
}
}
base.VisitBreak(statement);
}

protected int GetSwitchGoto(CiSwitch statement)
{
if (statement.Cases.Any(kase => CiSwitch.HasEarlyBreakAndContinue(kase.Body))
|| CiSwitch.HasEarlyBreakAndContinue(statement.DefaultBody)) {
this.SwitchesWithGoto.Add(statement);
return this.SwitchesWithGoto.Count - 1;
}
return -1;
}

protected void WriteIfCaseBody(List<CiStatement> body, bool doWhile)
{
int length = CiSwitch.LengthWithoutTrailingBreak(body);
if (doWhile && CiSwitch.HasEarlyBreak(body)) {
this.Indent++;
WriteNewLine();
Write("do ");
OpenBlock();
WriteFirstStatements(body, length);
CloseBlock();
WriteLine("while (0);");
this.Indent--;
}
else if (length == 1)
WriteChild(body[0]);
else {
WriteChar(' ');
OpenBlock();
WriteFirstStatements(body, length);
CloseBlock();
}
}

protected void EndSwitchAsIfs(CiSwitch statement, int gotoId)
{
if (statement.HasDefault()) {
Write("else");
WriteIfCaseBody(statement.DefaultBody, gotoId < 0);
}
if (gotoId >= 0) {
Write("ciafterswitch");
VisitLiteralLong(gotoId);
WriteLine(": ;");
}
}


}

}
Loading

0 comments on commit 2170d65

Please sign in to comment.