1aa8e87e310d813960d2db2000ade0508ceb0539 kent Thu Aug 8 14:17:30 2019 -0700 Improving commenting. diff --git src/lib/strex.c src/lib/strex.c index 4991b53..c72b1be 100644 --- src/lib/strex.c +++ src/lib/strex.c @@ -23,142 +23,144 @@ */ #include "common.h" #include "linefile.h" #include "hash.h" #include "dystring.h" #include "sqlNum.h" #include "localmem.h" #include "csv.h" #include "tokenizer.h" #include "hmac.h" #include "strex.h" enum strexType -/* A type */ +/* A type within parse tree or built in function specification. */ { strexTypeBoolean = 1, strexTypeString = 2, strexTypeInt = 3, strexTypeDouble = 4, }; enum strexBuiltInFunc -/* One of these for each builtIn. We'll just do a switch to implement */ +/* One of these for each builtIn. We'll just do a switch to implement + * Each built in function needs a value here, to keep it simple there's + * aa correspondence between these names and the built in function name */ { strexBuiltInTrim, strexBuiltInBetween, strexBuiltInSplit, strexBuiltInNow, strexBuiltInMd5, strexBuiltInSeparate, }; struct strexBuiltIn -/* A built in function */ +/* Information to describe a built in function */ { - char *name; - enum strexBuiltInFunc func; - int paramCount; - enum strexType *paramTypes; + char *name; /* Name in strex language: trim, split, etc */ + enum strexBuiltInFunc func; /* enum version: strexBuiltInTrim strexBuiltInSplit etc. */ + int paramCount; /* Number of parameters, not flexible in this language! */ + enum strexType *paramTypes; /* Array of types, one for each parameter */ }; - union strexVal /* Some value of arbirary type that can be of any type corresponding to strexType */ { boolean b; char *s; long long i; double x; struct strexBuiltIn *builtIn; }; struct strexEval /* Result of evaluation of parse tree. */ { enum strexType type; union strexVal val; }; enum strexOp /* An operation in the parse tree. */ { strexOpUnknown, /* Should not occur */ strexOpLiteral, /* Literal string or number. */ strexOpSymbol, /* A symbol name. */ strexOpBuiltInCall, /* Call a built in function */ strexOpArrayIx, /* An array with an index. */ + /* Unary minus for numbers */ strexOpUnaryMinusInt, strexOpUnaryMinusDouble, /* Binary operations. */ strexOpAdd, - /* Type conversions */ + /* Type conversions - possibly a few more than we actually need at the moment. */ strexOpStringToBoolean, strexOpIntToBoolean, strexOpDoubleToBoolean, strexOpStringToInt, strexOpDoubleToInt, strexOpBooleanToInt, strexOpStringToDouble, strexOpBooleanToDouble, strexOpIntToDouble, strexOpBooleanToString, strexOpIntToString, strexOpDoubleToString, }; - struct strexParse -/* A strex parse-tree. */ +/* A strex parse-tree node. The tree itself is just the root node. */ { struct strexParse *next; /* Points to younger sibling if any. */ struct strexParse *children; /* Points to oldest child if any. */ enum strexOp op; /* Operation at this node. */ enum strexType type; /* Return type of this operation. */ union strexVal val; /* Return value of this operation. */ }; struct strexIn -/* Input to the strex parser */ +/* Input to the strex parser - tokenizer and a hash full of built in functions. */ { struct tokenizer *tkz; /* Get next text input from here */ struct hash *builtInHash; /* Hash of built in functions */ }; +/* Some predefined lists of parameter types */ static enum strexType oneString[] = {strexTypeString}; // static enum strexType twoStrings[] = {strexTypeString, strexTypeString}; static enum strexType threeStrings[] = {strexTypeString, strexTypeString, strexTypeString}; static enum strexType stringInt[] = {strexTypeString, strexTypeInt}; static enum strexType stringStringInt[] = {strexTypeString, strexTypeString, strexTypeInt}; +/* There's one element here for each built in function. There's also a few switches you'll need to + * fill in if you add a new built in function. */ static struct strexBuiltIn builtins[] = { { "trim", strexBuiltInTrim, 1, oneString, }, { "between", strexBuiltInBetween, 3, threeStrings, }, { "split", strexBuiltInSplit, 2, stringInt }, { "now", strexBuiltInNow, 0, NULL }, { "md5", strexBuiltInMd5, 1, oneString }, { "separate", strexBuiltInSeparate, 3, stringStringInt }, }; - - static struct hash *hashBuiltIns() /* Build a hash of builtins keyed by name */ { struct hash *hash = hashNew(0); int i; for (i=0; i<ArraySize(builtins); ++i) hashAdd(hash, builtins[i].name, &builtins[i]); return hash; } static struct strexIn *strexInNew(char *expression) /* Return a new strexIn structure wrapped around expression */ { struct lineFile *lf = lineFileOnString(expression, TRUE, cloneString(expression)); struct tokenizer *tkz = tokenizerOnLineFile(lf); @@ -300,31 +302,31 @@ } static void skipOverRequired(struct strexIn *in, char *expecting) /* Make sure that next token is tok, and skip over it. */ { tokenizerMustHaveNext(in->tkz); if (!sameWord(in->tkz->string, expecting)) expectingGot(in, expecting, in->tkz->string); } static struct strexParse *strexParseExpression(struct strexIn *in); /* Parse out an expression with a single value */ static struct strexParse *strexParseAtom(struct strexIn *in) -/* Return low level (symbol or literal) */ +/* Return low level (symbol or literal) or a parenthesis enclosed expression. */ { struct tokenizer *tkz = in->tkz; char *tok = tokenizerMustHaveNext(tkz); struct strexParse *p; AllocVar(p); char c = tok[0]; if (c == '\'' || c == '"') { p->op = strexOpLiteral; p->type = strexTypeString; int len = strlen(tok+1); p->val.s = cloneStringZ(tok+1, len-1); } else if (isalpha(c) || c == '_') {