diff --git a/structs.scad b/structs.scad index bb0986c..1c9b2f7 100644 --- a/structs.scad +++ b/structs.scad @@ -12,99 +12,113 @@ // Section: struct operations // // A struct is a data structure that associates arbitrary keywords (of any type) with values (of any type). -// Structures are implemented as lists of [keyword, value] pairs. +// Structures are implemented as lists of [keyword, value] pairs. // // An empty list `[]` is an empty structure and can be used wherever a structure input is required. // Function: struct_set() // Usage: -// struct_set(struct, keyword, value, [grow]) -// struct_set(struct, [keyword1, value1, keyword2, value2, ...], [grow]) +// struct_set(struct, keyword, value, [grow]) +// struct_set(struct, [keyword1, value1, keyword2, value2, ...], [grow]) // Description: -// Sets the keyword(s) in the structure to the specified value(s), returning a new updated structure. If a keyword -// exists its value is changed, otherwise the keyword is added to the structure. If grow is set to false then -// it is an error to set a keyword not already defined in the structure. If you specify the same keyword twice -// that is also an error. If speed matters, use the first form with scalars rather than the list form: this is -// about thirty times faster. +// Sets the keyword(s) in the structure to the specified value(s), returning a new updated structure. If a keyword +// exists its value is changed, otherwise the keyword is added to the structure. If grow is set to false then +// it is an error to set a keyword not already defined in the structure. If you specify the same keyword twice +// that is also an error. If speed matters, use the first form with scalars rather than the list form: this is +// about thirty times faster. // Arguments: -// struct = input structure -// keyword = keyword to set -// value = value to set the keyword to -// grow = Set to true to allow structure to grow, or false for new keywords to generate an error. Default: true +// struct = Input structure. +// keyword = Keyword to set. +// value = Value to set the keyword to. +// grow = Set to true to allow structure to grow, or false for new keywords to generate an error. Default: true function struct_set(struct, keyword, value=undef, grow=true) = - !is_list(keyword) ? - let(ind=search([keyword],struct,1,0)[0]) - (ind==[] ? assert(grow,str("Unknown keyword \"",keyword)) - concat(struct, [[keyword,value]]) : - list_set(struct, [ind], [[keyword,value]])) : - _parse_pairs(struct,keyword,grow); + !is_list(keyword)? ( + let( ind=search([keyword],struct,1,0)[0] ) + ind==[]? ( + assert(grow,str("Unknown keyword \"",keyword)) + concat(struct, [[keyword,value]]) + ) : list_set(struct, [ind], [[keyword,value]]) + ) : _parse_pairs(struct,keyword,grow); + function _parse_pairs(spec, input, grow=true, index=0, result=undef) = - assert(len(input)%2==0,"Odd number of entries in [keyword,value] pair list") - let( result = result==undef ? spec : result) - index == len(input) ? result : - _parse_pairs(spec,input,grow,index+2,struct_set(result, input[index], input[index+1],grow)); + assert(len(input)%2==0,"Odd number of entries in [keyword,value] pair list") + let( result = result==undef ? spec : result) + index == len(input) ? result : + _parse_pairs(spec,input,grow,index+2,struct_set(result, input[index], input[index+1],grow)); + // Function: struct_remove() // Usage: -// struct_remove(struct, keyword) +// struct_remove(struct, keyword) // Description: -// Remove keyword or keyword list from a structure +// Remove keyword or keyword list from a structure // Arguments: -// struct = input structure -// keyword = a single string (keyword) or list of strings (keywords) to remove +// struct = input structure +// keyword = a single string (keyword) or list of strings (keywords) to remove function struct_remove(struct, keyword) = - is_string(keyword)? struct_remove(struct, [keyword]) : - let(ind = search(keyword, struct)) - list_remove(struct, ind); + is_string(keyword)? struct_remove(struct, [keyword]) : + let(ind = search(keyword, struct)) + list_remove(struct, ind); + // Function: struct_val() // Usage: -// struct_val(struct,keyword) +// struct_val(struct,keyword) // Description: -// Returns the value for the specified keyword in the structure, or undef if the keyword is not present +// Returns the value for the specified keyword in the structure, or undef if the keyword is not present // Arguments: -// struct = input structure -// keyword = keyword whose value to return +// struct = input structure +// keyword = keyword whose value to return function struct_val(struct,keyword) = - assert(is_def(keyword),"keyword is missing") - let(ind = search([keyword],struct)[0]) - ind == [] ? undef : struct[ind][1]; + assert(is_def(keyword),"keyword is missing") + let(ind = search([keyword],struct)[0]) + ind == [] ? undef : struct[ind][1]; + // Function: struct_keys() // Usage: -// struct_keys(struct) +// keys = struct_keys(struct) // Description: -// Returns a list of the keys in a structure +// Returns a list of the keys in a structure // Arguments: -// struct = input structure +// struct = input structure function struct_keys(struct) = - [for(entry=struct) entry[0]]; + [for(entry=struct) entry[0]]; -// Function&Module struct_echo() + +// Function&Module: struct_echo() // Usage: -// struct_echo(struct, [name]) +// struct_echo(struct, [name]) // Description: -// Displays a list of structure keywords and values, one pair per line, for easier reading. +// Displays a list of structure keywords and values, one pair per line, for easier reading. // Arguments: -// struct = input structure -// name = optional structure name to list at the top of the output. Default: "" +// struct = input structure +// name = optional structure name to list at the top of the output. Default: "" function struct_echo(struct,name="") = - let( keylist = [for(entry=struct) str("  ",entry[0],": ",entry[1],"\n")]) - echo(str("\nStructure ",name,"\n",str_join(keylist))) - undef; + let( keylist = [for(entry=struct) str("  ",entry[0],": ",entry[1],"\n")]) + echo(str("\nStructure ",name,"\n",str_join(keylist))) + undef; module struct_echo(struct,name="") { - dummy = struct_echo(struct,name); + dummy = struct_echo(struct,name); } -// Function is_struct() + +// Function: is_struct() // Usage: -// is_struct(struct) -// Description: Returns true if the input has the form of a structure, false otherwise. -function is_struct(struct, ind=0) = - is_list(struct) && ( - struct == [] || - let(dim = array_dim(struct)) - len(dim)==2 && dim[1]==2 - ); +// is_struct(struct) +// Description: +// Returns true if the input has the form of a structure, false otherwise. +function is_struct(x) = + is_list(x) && [ + for (xx=x) if( + !is_list(xx) || + len(xx) != 2 || + !is_string(xx[0]) + ) 1 + ] == []; + + + +// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap diff --git a/version.scad b/version.scad index 4b407fa..9cfb5eb 100644 --- a/version.scad +++ b/version.scad @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,310]; +BOSL_VERSION = [2,0,311]; // Section: BOSL Library Version Functions