Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added runtime tests and implementation for switch statements on strings.

  • Loading branch information...
commit 48617d513beab33b57e6cdd47d040e9898bb98ed 1 parent c37e299
@wilkie authored
View
4 Makefile
@@ -42,7 +42,7 @@ DFILES_LOCALES = locales/en_us.d locales/fr_fr.d locales/all.d
DFILES_CORE = core/date.d core/locale.d core/variant.d core/exception.d core/event.d core/library.d core/system.d core/regex.d core/arguments.d core/definitions.d core/application.d core/time.d core/timezone.d core/unicode.d core/endian.d core/stream.d core/string.d core/main.d core/color.d
DFILES_GUI = gui/container.d gui/trackbar.d gui/radiogroup.d gui/progressbar.d gui/togglefield.d gui/listfield.d gui/listbox.d gui/vscrollbar.d gui/hscrollbar.d gui/button.d gui/textfield.d gui/window.d gui/widget.d gui/application.d
DFILES_DATA = data/stack.d data/queue.d data/queue2.d data/fibonacci.d data/heap.d data/list.d data/iterable.d
-DFILES_RUNTIME = runtime/array.d runtime/apply.d
+DFILES_RUNTIME = runtime/array.d runtime/apply.d runtime/switchstmt.d
DFILES_PARSING = parsing/d/trees.d parsing/d/addexprunit.d parsing/d/andexprunit.d parsing/d/assignexprunit.d parsing/d/blockstmtunit.d parsing/d/switchstmtunit.d parsing/d/casestmtunit.d parsing/d/defaultstmtunit.d parsing/d/breakstmtunit.d parsing/d/continuestmtunit.d parsing/d/gotostmtunit.d parsing/d/returnstmtunit.d parsing/d/volatilestmtunit.d parsing/d/throwstmtunit.d parsing/d/postfixexprlistunit.d parsing/d/cmpexprunit.d parsing/d/conditionalexprunit.d parsing/d/declarationunit.d parsing/d/expressionunit.d parsing/d/importdeclunit.d parsing/d/isexprunit.d parsing/d/lexer.d parsing/d/logicalandexprunit.d parsing/d/logicalorexprunit.d parsing/d/moduledeclunit.d parsing/d/moduleunit.d parsing/d/mulexprunit.d parsing/d/nodes.d parsing/d/orexprunit.d parsing/d/parser.d parsing/d/postfixexprunit.d parsing/d/primaryexprunit.d parsing/d/shiftexprunit.d parsing/d/staticunit.d parsing/d/declaratorunit.d parsing/d/declaratorsuffixunit.d parsing/d/declaratortypeunit.d parsing/d/tokens.d parsing/d/enumdeclunit.d parsing/d/typeunit.d parsing/d/enumbodyunit.d parsing/d/aggregatedeclunit.d parsing/d/aggregatebodyunit.d parsing/d/classbodyunit.d parsing/d/templatebodyunit.d parsing/d/interfacebodyunit.d parsing/d/classdeclunit.d parsing/d/interfacedeclunit.d parsing/d/constructorunit.d parsing/d/destructorunit.d parsing/d/parameterlistunit.d parsing/d/functionbodyunit.d parsing/d/staticifunit.d parsing/d/versionunit.d parsing/d/debugunit.d parsing/d/unittestunit.d parsing/d/parameterunit.d parsing/d/basictypeunit.d parsing/d/statementunit.d parsing/d/pragmastmtunit.d parsing/d/staticassertunit.d parsing/d/foreachstmtunit.d parsing/d/scopedstmtunit.d parsing/d/forstmtunit.d parsing/d/typedeclarationunit.d parsing/d/unaryexprunit.d parsing/d/xorexprunit.d parsing/ast.d parsing/lexer.d parsing/token.d parsing/parser.d parsing/options.d parsing/cfg.d parsing/parseunit.d
DFILES = djehuty.d
DFILES_BINARY_CODECS = decoders/binary/decoder.d decoders/binary/base64.d decoders/binary/yEnc.d decoders/binary/deflate.d decoders/binary/zlib.d
@@ -65,7 +65,7 @@ DFILES_TESTING = spec/support.d spec/logic.d spec/itemspecification.d spec/packa
DFILES_SYNCH = synch/atomic.d synch/condition.d synch/barrier.d synch/mutex.d synch/semaphore.d synch/thread.d synch/timer.d
DFILES_RSC =
-DFILES_SPECS = .specs/runtime/array.d .specs/runtime/apply.d .specs/core/application.d .specs/core/arguments.d .specs/core/date.d .specs/core/exception.d .specs/core/regex.d .specs/core/string.d .specs/core/time.d .specs/core/unicode.d .specs/core/util.d .specs/core/variant.d .specs/data/fibonacci.d .specs/data/heap.d .specs/data/queue.d .specs/data/stack.d .specs/hashes/digest.d .specs/hashes/md5.d .specs/hashes/sha1.d .specs/hashes/sha224.d .specs/hashes/sha256.d .specs/math/random.d
+DFILES_SPECS = .specs/runtime/array.d .specs/runtime/foreach.d .specs/core/application.d .specs/core/arguments.d .specs/core/date.d .specs/core/exception.d .specs/core/regex.d .specs/core/string.d .specs/core/time.d .specs/core/unicode.d .specs/core/util.d .specs/core/variant.d .specs/data/fibonacci.d .specs/data/heap.d .specs/data/queue.d .specs/data/stack.d .specs/hashes/digest.d .specs/hashes/md5.d .specs/hashes/sha1.d .specs/hashes/sha224.d .specs/hashes/sha256.d .specs/math/random.d .specs/runtime/switch.d
SOURCES = $(DFILES_SPECS) $(DFILES) $(DFILES_RUNTIME) $(DFILES_LOCALES) $(DFILES_RESOURCE) $(DFILES_IO) $(DFILES_SYNCH) $(DFILES_PARSING) $(DFILES_OPENGL) $(DFILES_CUI) $(DFILES_ANALYZING) $(DFILES_SCRIPTING) $(DFILES_BINDING) $(DFILES_TESTING) $(DFILES_MATH) $(DFILES_GRAPHICS) $(DFILES_HASHES) $(DFILES_RSC) $(DFILES_NETWORKING) $(DFILES_INTERFACES) $(DFILES_DATA) $(DFILES_CONSOLE) $(DFILES_BINARY_CODECS) $(DFILES_CODEC) $(DFILES_IMAGE_CODECS) $(DFILES_AUDIO_CODECS) $(DFILES_CORE) $(DFILES_GUI) $(DFILES_PARSERS)
View
28 core/util.d
@@ -222,3 +222,31 @@ private template RemoveSpacesImpl(char[] foo, uint pos = 0) {
template RemoveSpaces(char[] foo) {
const char[] RemoveSpaces = RemoveSpacesImpl!(foo);
}
+
+template Itoa(long i) {
+ static if(i < 0) {
+ const char[] Itoa = "-" ~ IntToStr!(-i, 10);
+ }
+ else {
+ const char[] Itoa = IntToStr!(i, 10);
+ }
+}
+
+template Itoh(long i) {
+ const char[] Itoh = "0x" ~ IntToStr!(i, 16);
+}
+
+template Digits(long i) {
+ const char[] Digits = "0123456789abcdefghijklmnopqrstuvwxyz"[0 .. i];
+}
+
+template IntToStr(ulong i, int base) {
+ static if(i >= base) {
+ const char[] IntToStr = IntToStr!(i / base, base) ~ Digits!(base)[i % base];
+ }
+ else {
+ const char[] IntToStr = "" ~ Digits!(base)[i % base];
+ }
+}
+
+
View
62 runtime/switchstmt.d
@@ -8,28 +8,78 @@
module runtime.switchstmt;
+private template _switch_string(T) {
+ int _switch_string(T[][] table, T[] compare) {
+ if (table.length == 0) {
+ return -1;
+ }
+
+ // Optimization for empty string, it must be first in sorted table
+ if (compare.length == 0) {
+ if (table[0] == compare) {
+ return 0;
+ }
+ return -1;
+ }
+
+ TypeInfo ti = typeid(T[]);
+
+ // Binary search the table
+ size_t min = 0;
+ size_t max = table.length;
+
+ // Current comparing position
+ size_t cur; // midpoint
+
+ // Temp for compare value
+ int cmp;
+
+ while(max > min) {
+ cur = (max + min) / 2;
+ if (table[cur].length == compare.length) {
+ cmp = ti.compare(&table[cur], &compare);
+ }
+ else {
+ cmp = table[cur].length - compare.length;
+ }
+
+ if (cmp == 0) {
+ return cur;
+ }
+ else if (cmp > 0) {
+ max = cur;
+ }
+ else {
+ min = cur + 1;
+ }
+ }
+
+ return -1;
+ }
+}
+
extern(C):
// Description: This runtime function will search the given sorted list of
// UTF8 strings and locate the string given.
// Returns: The index into table where the given string was located and -1
// if it was not found.
-int _d_switch_string(char[][] table, char[] ca) {
- return 0;
+int _d_switch_string(char[][] table, char[] compare) {
+ return _switch_string(table, compare);
}
// Description: This runtime function will search the given sorted list of
// UTF16 strings and locate the string given.
// Returns: The index into table where the given string was located and -1
// if it was not found.
-int _d_switch_ustring(wchar[][] table, wchar[] ca) {
- return 0;
+int _d_switch_ustring(wchar[][] table, wchar[] compare) {
+ return _switch_string(table, compare);
}
// Description: This runtime function will search the given sorted list of
// UTF32 strings and locate the string given.
// Returns: The index into table where the given string was located and -1
// if it was not found.
-int _d_switch_dstring(dchar[][] table, dchar[] ca) {
- return 0;
+int _d_switch_dstring(dchar[][] table, dchar[] compare) {
+ return _switch_string(table, compare);
}
View
2  specs/runtime/apply.ds → specs/runtime/foreach.ds
@@ -1,4 +1,4 @@
-module specs.runtime.apply;
+module specs.runtime.foreach;
import io.console;
View
122 specs/runtime/switch.ds
@@ -0,0 +1,122 @@
+module specs.runtime.switch;
+
+import core.util;
+
+import math.random;
+
+describe runtime() {
+ describe _d_switch_string {
+ it should_handle_empty_switch_statements {
+ string foo = "hello";
+
+ switch(foo) {
+ default:
+ break;
+ }
+ }
+
+ it should_handle_one_case {
+ string foo = "hello";
+
+ switch(foo) {
+ case "hello":
+ should(true);
+ break;
+ default:
+ should(false);
+ break;
+ }
+ }
+
+ it should_handle_three_cases {
+ string foo = "hello";
+
+ switch(foo) {
+ case "abc":
+ case "zzt":
+ should(false);
+ break;
+ case "hello":
+ should(true);
+ break;
+ default:
+ should(false);
+ break;
+ }
+ }
+
+ template StringList(int idx) {
+ static if (idx == 50) {
+ const char[] StringList = `"` ~ IntToStr!(idx, 16) ~ `"
+ `;
+ }
+ else {
+ const char[] StringList = `"` ~ IntToStr!(idx, 16) ~ `",
+ ` ~ StringList!(idx+1);
+ }
+ }
+
+ template StringArray() {
+ const char[] StringArray = `
+ string[] foo = [
+ ` ~ StringList!(0) ~ `
+ ];`;
+ }
+
+ template CaseList(int idx) {
+ static if (idx == 50) {
+ const char[] CaseList = `case "` ~ IntToStr!(idx, 16) ~ `":
+ picked = "` ~ IntToStr!(idx, 16) ~ `";
+ break;`;
+ }
+ else {
+ const char[] CaseList = `case "` ~ IntToStr!(idx, 16) ~ `":
+ picked = "` ~ IntToStr!(idx, 16) ~ `";
+ break;
+ ` ~ CaseList!(idx+1);
+ }
+ }
+
+ template SwitchList() {
+ const char[] SwitchList = `
+ switch(foo[idx]) {
+ ` ~ CaseList!(0) ~ `
+ default:
+ picked = "";
+ break;
+ }`;
+ }
+
+ it should_handle_many_cases {
+
+ mixin(StringArray!());
+
+ auto r = new Random();
+ for (size_t i=0; i<50; i++) {
+ size_t idx = cast(size_t)r.nextLong(50);
+ string picked;
+
+ mixin(SwitchList!());
+
+ should(picked == foo[idx]);
+ }
+ }
+
+ it should_handle_empty_string {
+ switch("") {
+ case "":
+ should(true);
+ break;
+ case "abc":
+ case "zsdf":
+ case "asdf":
+ case "afsfdfas":
+ should(false);
+ break;
+ default:
+ should(false);
+ break;
+ }
+ }
+ }
+}
View
2  tools/dspec/feeder.d
@@ -7,7 +7,7 @@ import core.definitions;
import io.file;
import io.console;
-char[] delims = " \t.{}()[];,-+=/\\*&^%!|?:<>";
+char[] delims = " \t.{}()[];,-+=/\\*&^%!|?:<>`\"'";
class Feeder {
this(string filename) {
View
4 tools/dspec/output.d
@@ -53,8 +53,6 @@ class Output {
printImport(node);
break;
case "ParseModule":
- Console.putln("module");
-
AST work = node;
while (work !is null) {
node = work.right;
@@ -64,11 +62,9 @@ class Output {
else {
string content;
node.getValue(content);
- Console.putln(content);
moduleName = content.trim();
packageName = moduleName.substring(0, moduleName.findReverse("."));
moduleName = moduleName.substring(packageName.length+1);
- Console.putln("p:", packageName, "m:", moduleName);
}
}
View
1  tools/dspec/parser.d
@@ -31,7 +31,6 @@ class Parser {
dir = Directory.openOrCreate(filepath);
}
output = new Output(outputPath ~ f[inputPath.length..$-1]);
- Console.putln("!!!!", f[inputPath.length..$]);
if (!(parseFile(f))) {
return false;
}
View
58 winsamp.d
@@ -60,6 +60,43 @@ import parsing.d.parser;
import networking.ftp;
+private template _switch_string(T) {
+ int _switch_string(T[][] table, T[] compare) {
+ if (table.length == 0) {
+ return -1;
+ }
+
+ TypeInfo ti = typeid(T[]);
+ // Binary search the table
+ size_t min = 0;
+ size_t max = table.length;
+
+ // Current comparing position
+ size_t cur;
+
+ // Temp for compare value
+ int cmp;
+
+ while(max > min) {
+ cur = (max + min) / 2;
+ cmp = ti.compare(&table[cur], &compare);
+
+ if (cmp == 0) {
+ return cur;
+ }
+ else if (cmp > 0) {
+ max = cur;
+ }
+ else {
+ min = cur + 1;
+ }
+ }
+
+ return -1;
+ }
+}
+
+
import spec.specification;
import data.queue2;
@@ -192,6 +229,27 @@ class MyConsoleApp : Application {
Console.putln([3,2,1].sort);
Console.putln([[1,2],[2,3],[3],[1],[0]].sort);
+ dstring[] fuzz = [
+ "abc",
+ "zzt"
+ "hello",
+ ];
+
+ string foobe = "hello";
+
+ switch(foobe) {
+ case "abc":
+ case "zzt":
+ break;
+ case "hello":
+ Console.putln("yay");
+ break;
+ default:
+ break;
+ }
+
+ Console.putln(_switch_string(fuzz, "hello"d));
+
for(;;){}
}
Please sign in to comment.
Something went wrong with that request. Please try again.