Skip to content

Commit fc3c0ef

Browse files
Add D language. (#608)
* All the prepwork for D. * Everything for functionality seems to be done. * Update Makefile * Update Dockerfile * Removed duplicate switch condition * Put the final touches on the image * Image size fix * Update .gitignore * Update .dockerignore * Update d.svg * Update a-schema.sql * Update tmper.d
1 parent 3e79449 commit fc3c0ef

File tree

16 files changed

+326
-4
lines changed

16 files changed

+326
-4
lines changed

build-langs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ for %langs{ @langs || * }:p.sort -> (:key($name), :value(%lang)) {
4444
my $digits = $ver ~~ / <[\d.]>+ \d+ /;
4545

4646
when 'C#'
47+
| 'D'
4748
| 'F#'
4849
| 'PowerShell' { }
4950
when 'C' { $ver = "Tiny C Compiler $digits" }

config/langs.toml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,29 @@ ARGV.each do |arg|
241241
end
242242
'''
243243

244+
[D]
245+
size = '241 MiB'
246+
version = 'D 2.098.1 on LDC 1.28.1'
247+
website = 'https://dlang.org'
248+
example = '''
249+
import std.stdio;
250+
251+
void main(string[] args) {
252+
// Printing
253+
writeln("Hello, World!");
254+
255+
// Looping
256+
foreach (i; 0 .. 10) {
257+
writeln(i);
258+
}
259+
260+
// Accessing arguments
261+
foreach (arg; args) {
262+
writeln(arg);
263+
}
264+
}
265+
'''
266+
244267
['F#']
245268
size = '139 MiB'
246269
version = 'F# 6.0 on .NET 6.0.1'

css/golfer/holes.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ input.c:not(:checked) ~ .c,
4040
input.cobol:not(:checked) ~ .cobol,
4141
input.crystal:not(:checked) ~ .crystal,
4242
input.cpp:not(:checked) ~ .cpp,
43+
input.d:not(:checked) ~ .d,
4344
input.f-sharp:not(:checked) ~ .f-sharp,
4445
input.fish:not(:checked) ~ .fish,
4546
input.fortran:not(:checked) ~ .fortran,
@@ -92,7 +93,7 @@ main svg:nth-of-type(2) {
9293

9394
@media (min-width: 95rem) {
9495
/* Increase this number when adding a language. */
95-
main { grid-template-columns: 4fr repeat(36, 1fr) }
96+
main { grid-template-columns: 4fr repeat(37, 1fr) }
9697

9798
main a { height: 1.9rem }
9899

db/a-schema.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ CREATE TYPE keymap AS ENUM ('default', 'vim');
4242

4343
CREATE TYPE lang AS ENUM (
4444
'assembly', 'bash', 'brainfuck', 'c', 'c-sharp', 'cpp', 'cobol',
45-
'crystal', 'f-sharp', 'fish', 'fortran', 'go', 'haskell', 'hexagony', 'j',
45+
'crystal', 'd', 'f-sharp', 'fish', 'fortran', 'go', 'haskell', 'hexagony', 'j',
4646
'java', 'javascript', 'julia', 'k', 'lisp', 'lua', 'nim', 'pascal',
4747
'perl', 'php', 'powershell', 'prolog', 'python', 'raku', 'ruby', 'rust',
4848
'sql', 'swift', 'v', 'viml', 'zig'

docker/dev.Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ COPY --from=codegolf/lang-haskell ["/", "/langs/haskell/rootfs/" ] # 309 M
1212
COPY --from=codegolf/lang-julia ["/", "/langs/julia/rootfs/" ] # 278 MiB
1313
COPY --from=codegolf/lang-zig ["/", "/langs/zig/rootfs/" ] # 270 MiB
1414
COPY --from=codegolf/lang-crystal ["/", "/langs/crystal/rootfs/" ] # 242 MiB
15+
COPY --from=codegolf/lang-d ["/", "/langs/d/rootfs/" ] # 241 MiB
1516
COPY --from=codegolf/lang-powershell ["/", "/langs/powershell/rootfs/"] # 177 MiB
1617
COPY --from=codegolf/lang-c-sharp ["/", "/langs/c-sharp/rootfs/" ] # 144 MiB
1718
COPY --from=codegolf/lang-f-sharp ["/", "/langs/f-sharp/rootfs/" ] # 139 MiB

docker/live.Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ COPY --from=codegolf/lang-haskell ["/", "/langs/haskell/rootfs/" ] # 309 M
2525
COPY --from=codegolf/lang-julia ["/", "/langs/julia/rootfs/" ] # 278 MiB
2626
COPY --from=codegolf/lang-zig ["/", "/langs/zig/rootfs/" ] # 270 MiB
2727
COPY --from=codegolf/lang-crystal ["/", "/langs/crystal/rootfs/" ] # 242 MiB
28+
COPY --from=codegolf/lang-d ["/", "/langs/d/rootfs/" ] # 241 MiB
2829
COPY --from=codegolf/lang-powershell ["/", "/langs/powershell/rootfs/"] # 177 MiB
2930
COPY --from=codegolf/lang-c-sharp ["/", "/langs/c-sharp/rootfs/" ] # 144 MiB
3031
COPY --from=codegolf/lang-f-sharp ["/", "/langs/f-sharp/rootfs/" ] # 139 MiB

hole/play.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,10 @@ func getAnswer(holeID, code string) (args []string, answer string) {
9595
args, answer = qr(holeID == "qr-decoder")
9696
case "quine":
9797
answer = code
98-
case "rock-paper-scissors-spock-lizard":
99-
args, answer = rockPaperScissorsSpockLizard()
10098
case "reverse-polish-notation":
10199
args, answer = reversePolishNotation()
100+
case "rock-paper-scissors-spock-lizard":
101+
args, answer = rockPaperScissorsSpockLizard()
102102
case "seven-segment":
103103
args, answer = sevenSegment()
104104
case "spelling-numbers":
@@ -166,6 +166,8 @@ func Play(ctx context.Context, holeID, langID, code string) (score Scorecard) {
166166
case "crystal":
167167
cmd.Args = []string{"/usr/bin/crystal", "run", "--stdin-filename", "code.cr", "--"}
168168
cmd.Env = []string{"CRYSTAL_CACHE_DIR=/tmp", "PATH=/usr/bin:/bin"}
169+
case "d":
170+
cmd.Args = []string{"/usr/bin/tmper", "--run", "/tmp/code.d"}
169171
case "fish":
170172
cmd.Args = []string{"/usr/bin/fish", "--no-prng", "-c", code, "-u"}
171173
case "haskell", "php":

js/_codemirror-legacy.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import './codemirror-legacy/_bash';
1010
import './codemirror-legacy/_brainfuck';
1111
import './codemirror-legacy/_cobol';
1212
import './codemirror-legacy/_crystal';
13+
import './codemirror-legacy/_d';
1314
import './codemirror-legacy/_fortran';
1415
import './codemirror-legacy/_go';
1516
import './codemirror-legacy/_haskell';

js/_codemirror.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { cobol } from '@codemirror/legacy-modes/mode/cobol';
2222
import { commonLisp } from '@codemirror/legacy-modes/mode/commonlisp';
2323
import { cpp } from '@codemirror/lang-cpp';
2424
import { crystal } from '@codemirror/legacy-modes/mode/crystal';
25+
import { d } from '@codemirror/legacy-modes/mode/d'
2526
import { fortran } from '@codemirror/legacy-modes/mode/fortran';
2627
import { fSharp } from '@codemirror/legacy-modes/mode/mllike';
2728
import { go } from '@codemirror/legacy-modes/mode/go';
@@ -95,6 +96,7 @@ export const extensions = {
9596
'cobol': StreamLanguage.define(cobol),
9697
'cpp': cpp(),
9798
'crystal': StreamLanguage.define(crystal),
99+
'd': StreamLanguage.define(d),
98100
'f-sharp': StreamLanguage.define(fSharp),
99101
// TODO fish
100102
'fortran': StreamLanguage.define(fortran),

js/codemirror-legacy/_d.js

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
// CodeMirror, copyright (c) by Marijn Haverbeke and others
2+
// Distributed under an MIT license: https://codemirror.net/LICENSE
3+
4+
(function(mod) {
5+
mod(require("./_codemirror"));
6+
})(function(CodeMirror) {
7+
"use strict";
8+
9+
CodeMirror.defineMode("d", function(config, parserConfig) {
10+
var indentUnit = config.indentUnit,
11+
statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
12+
keywords = parserConfig.keywords || {},
13+
builtin = parserConfig.builtin || {},
14+
blockKeywords = parserConfig.blockKeywords || {},
15+
atoms = parserConfig.atoms || {},
16+
hooks = parserConfig.hooks || {},
17+
multiLineStrings = parserConfig.multiLineStrings;
18+
var isOperatorChar = /[+\-*&%=<>!?|\/]/;
19+
20+
var curPunc;
21+
22+
function tokenBase(stream, state) {
23+
var ch = stream.next();
24+
if (hooks[ch]) {
25+
var result = hooks[ch](stream, state);
26+
if (result !== false) return result;
27+
}
28+
if (ch == '"' || ch == "'" || ch == "`") {
29+
state.tokenize = tokenString(ch);
30+
return state.tokenize(stream, state);
31+
}
32+
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
33+
curPunc = ch;
34+
return null;
35+
}
36+
if (/\d/.test(ch)) {
37+
stream.eatWhile(/[\w\.]/);
38+
return "number";
39+
}
40+
if (ch == "/") {
41+
if (stream.eat("+")) {
42+
state.tokenize = tokenNestedComment;
43+
return tokenNestedComment(stream, state);
44+
}
45+
if (stream.eat("*")) {
46+
state.tokenize = tokenComment;
47+
return tokenComment(stream, state);
48+
}
49+
if (stream.eat("/")) {
50+
stream.skipToEnd();
51+
return "comment";
52+
}
53+
}
54+
if (isOperatorChar.test(ch)) {
55+
stream.eatWhile(isOperatorChar);
56+
return "operator";
57+
}
58+
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
59+
var cur = stream.current();
60+
if (keywords.propertyIsEnumerable(cur)) {
61+
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
62+
return "keyword";
63+
}
64+
if (builtin.propertyIsEnumerable(cur)) {
65+
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
66+
return "builtin";
67+
}
68+
if (atoms.propertyIsEnumerable(cur)) return "atom";
69+
return "variable";
70+
}
71+
72+
function tokenString(quote) {
73+
return function(stream, state) {
74+
var escaped = false, next, end = false;
75+
while ((next = stream.next()) != null) {
76+
if (next == quote && !escaped) {end = true; break;}
77+
escaped = !escaped && next == "\\";
78+
}
79+
if (end || !(escaped || multiLineStrings))
80+
state.tokenize = null;
81+
return "string";
82+
};
83+
}
84+
85+
function tokenComment(stream, state) {
86+
var maybeEnd = false, ch;
87+
while (ch = stream.next()) {
88+
if (ch == "/" && maybeEnd) {
89+
state.tokenize = null;
90+
break;
91+
}
92+
maybeEnd = (ch == "*");
93+
}
94+
return "comment";
95+
}
96+
97+
function tokenNestedComment(stream, state) {
98+
var maybeEnd = false, ch;
99+
while (ch = stream.next()) {
100+
if (ch == "/" && maybeEnd) {
101+
state.tokenize = null;
102+
break;
103+
}
104+
maybeEnd = (ch == "+");
105+
}
106+
return "comment";
107+
}
108+
109+
function Context(indented, column, type, align, prev) {
110+
this.indented = indented;
111+
this.column = column;
112+
this.type = type;
113+
this.align = align;
114+
this.prev = prev;
115+
}
116+
function pushContext(state, col, type) {
117+
var indent = state.indented;
118+
if (state.context && state.context.type == "statement")
119+
indent = state.context.indented;
120+
return state.context = new Context(indent, col, type, null, state.context);
121+
}
122+
function popContext(state) {
123+
var t = state.context.type;
124+
if (t == ")" || t == "]" || t == "}")
125+
state.indented = state.context.indented;
126+
return state.context = state.context.prev;
127+
}
128+
129+
// Interface
130+
131+
return {
132+
startState: function(basecolumn) {
133+
return {
134+
tokenize: null,
135+
context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
136+
indented: 0,
137+
startOfLine: true
138+
};
139+
},
140+
141+
token: function(stream, state) {
142+
var ctx = state.context;
143+
if (stream.sol()) {
144+
if (ctx.align == null) ctx.align = false;
145+
state.indented = stream.indentation();
146+
state.startOfLine = true;
147+
}
148+
if (stream.eatSpace()) return null;
149+
curPunc = null;
150+
var style = (state.tokenize || tokenBase)(stream, state);
151+
if (style == "comment" || style == "meta") return style;
152+
if (ctx.align == null) ctx.align = true;
153+
154+
if ((curPunc == ";" || curPunc == ":" || curPunc == ",") && ctx.type == "statement") popContext(state);
155+
else if (curPunc == "{") pushContext(state, stream.column(), "}");
156+
else if (curPunc == "[") pushContext(state, stream.column(), "]");
157+
else if (curPunc == "(") pushContext(state, stream.column(), ")");
158+
else if (curPunc == "}") {
159+
while (ctx.type == "statement") ctx = popContext(state);
160+
if (ctx.type == "}") ctx = popContext(state);
161+
while (ctx.type == "statement") ctx = popContext(state);
162+
}
163+
else if (curPunc == ctx.type) popContext(state);
164+
else if (((ctx.type == "}" || ctx.type == "top") && curPunc != ';') || (ctx.type == "statement" && curPunc == "newstatement"))
165+
pushContext(state, stream.column(), "statement");
166+
state.startOfLine = false;
167+
return style;
168+
},
169+
170+
indent: function(state, textAfter) {
171+
if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
172+
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
173+
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
174+
var closing = firstChar == ctx.type;
175+
if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
176+
else if (ctx.align) return ctx.column + (closing ? 0 : 1);
177+
else return ctx.indented + (closing ? 0 : indentUnit);
178+
},
179+
180+
electricChars: "{}",
181+
blockCommentStart: "/*",
182+
blockCommentEnd: "*/",
183+
blockCommentContinue: " * ",
184+
lineComment: "//",
185+
fold: "brace"
186+
};
187+
});
188+
189+
function words(str) {
190+
var obj = {}, words = str.split(" ");
191+
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
192+
return obj;
193+
}
194+
195+
var blockKeywords = "body catch class do else enum for foreach foreach_reverse if in interface mixin " +
196+
"out scope struct switch try union unittest version while with";
197+
198+
CodeMirror.defineMIME("text/x-d", {
199+
name: "d",
200+
keywords: words("abstract alias align asm assert auto break case cast cdouble cent cfloat const continue " +
201+
"debug default delegate delete deprecated export extern final finally function goto immutable " +
202+
"import inout invariant is lazy macro module new nothrow override package pragma private " +
203+
"protected public pure ref return shared short static super synchronized template this " +
204+
"throw typedef typeid typeof volatile __FILE__ __LINE__ __gshared __traits __vector __parameters " +
205+
blockKeywords),
206+
blockKeywords: words(blockKeywords),
207+
builtin: words("bool byte char creal dchar double float idouble ifloat int ireal long real short ubyte " +
208+
"ucent uint ulong ushort wchar wstring void size_t sizediff_t"),
209+
atoms: words("exit failure success true false null"),
210+
hooks: {
211+
"@": function(stream, _state) {
212+
stream.eatWhile(/[\w\$_]/);
213+
return "meta";
214+
}
215+
}
216+
});
217+
218+
});

0 commit comments

Comments
 (0)