[Nickle] nickle: Branch 'master'

Bart Massey bart at keithp.com
Wed Jul 10 15:12:41 PDT 2013


 math.5c   |   20 ++++++++++++++++++++
 string.5c |   26 ++++++++++++++++++--------
 2 files changed, 38 insertions(+), 8 deletions(-)

New commits:
commit 8de064cd50660797959b7988ce15b5e2a51ae946
Author: Bart Massey <bart at cs.pdx.edu>
Date:   Wed Jul 10 15:11:08 2013 -0700

    Added a lightly-optimized choose(n, k) function to math.5c.
    
    The lack of a choose operator has continually bugged me;
    I've constantly rewritten it "the bad way". This is a
    lightly optimized version of that function that seems to
    handle most edge cases reasonably. It has only been tested a
    little bit.

diff --git a/math.5c b/math.5c
index a6cd170..673ad46 100644
--- a/math.5c
+++ b/math.5c
@@ -1014,6 +1014,26 @@ extend namespace Math {
 	return ul;
     }
 
+    public int choose(int n, int k)
+        /* Number of ways of choosing k items from a set of
+           n distinct items. */
+    {
+        /* This keeps the size of the intermediate terms
+           smaller below, and also makes the bounds check
+           slightly easier. */
+        if (k > (n + 1) // 2)
+            k = n - k;
+        if (n < 0 || k < 0)
+            return 0;
+        int c = 1;
+        /* This keeps the size of the intermediate terms
+           down a bit compared to the traditional
+           computation.  It probably doesn't matter, but oh
+           well. */
+        for (int i = n - k + 1; i <= n; i++)
+            c *= i;
+        return c / k!;
+    }
 }
 
 /* XXX these shouldn't be here, but it was *convenient* */
diff --git a/string.5c b/string.5c
index 52bae33..52e3878 100644
--- a/string.5c
+++ b/string.5c
@@ -193,18 +193,28 @@ extend namespace String {
     public exception bad_csv_parse(string error_msg,
     	   	                   string[*] partial_parse);
 
-    public parse_csv_t make_parse_csv(quote_context q) 
+    public parse_csv_t make_parse_csv(int sep, quote_context q)
 	/*
 	 * Construct a CSV file parsing context from 'q'
 	 */
     {
+        if (length(q.oq) != 1 || length(q.cq) != 1 || length(q.qq) > 1)
+	    raise invalid_argument("make_parse_csv: quote context"
+				   + "has long bits", 0, q);
+	global bool equiv(int c, &string s) {
+	    if (is_uninit(&s))
+		return false;
+	    if (s[0] != c)
+		return false;
+	    return true;
+	}
 	dequote_t dq = make_dequote(q);
 	public string[*] _parse_csv(string s) {
 	    string[...] ss = {};
 	    string curs = "";
 	    void consume() {
 		string t = chomp(curs);
-		if (t != "" && t[0] == '"')
+		if (t != "" && t == q.oq)
 		    t = dq(t);
 		ss[dim(ss)] = t;
 		curs = "";
@@ -215,24 +225,24 @@ extend namespace String {
 		int c = s[cur];
 		switch(t) {
 		case qstate.normal:
-		    if (c == ',') {
+		    if (c == sep) {
 			consume();
 			cur++;
 			continue;
 		    }
-		    if (c == '"')
+		    if (equiv(c, &q.oq))
 			t = qstate.openq;
 		    break;
 		case qstate.openq:
-		    if (c == '"')
+		    if (equiv(c, &q.cq))
 			t = qstate.xq;
 		    break;
 		case qstate.xq:
-		    if (c == '"') {
+		    if (equiv(c, &q.oq)) {
 			t = qstate.openq;
 			break;
 		    }
-		    if (c == ',') {
+		    if (c == sep) {
 			t = qstate.normal;
 			continue;
 		    }
@@ -251,7 +261,7 @@ extend namespace String {
 	return _parse_csv;
     }
 
-    public parse_csv_t parse_csv = make_parse_csv(
+    public parse_csv_t parse_csv = make_parse_csv( ',',
        (quote_context) { .oq = "\"", .cq = "\"", .qq = "\""}
     );
 


More information about the Nickle mailing list