Changeset b1b513d
- Timestamp:
- Apr 10, 2025, 5:27:36 PM (6 months ago)
- Branches:
- master
- Children:
- 234c432
- Parents:
- 6174ecc (diff), bb506e0 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/fangren_yu_MMath/conclusion.tex
r6174ecc rb1b513d 1 1 \chapter{Conclusion} 2 2 3 The goal of this thesis is to ... 3 In the past few years of development, \CFA has gone from a proof-of-concept prototype to an actual experimental language, with a few medium-sized projects written completely in \CFA included in the language's libraries ($\approx$\,45,000 lines of code).\footnote{In Fall 2024, two amazing CS343 students completed all 6 concurrent assignments in \CFA. Many small language problems were uncovered and missing features discovered; these issues are being fixed for Fall 2025.} 4 The work done in this thesis is motivated by real needs arising from the development and testing of these projects, which often pushes the limits of \CFA's type system and compiler capabilities. 5 While most of the previous \CFA language feature and compiler developments were done either in isolation or with limited testing, getting them to work together and with real projects is presenting significant new challenges. 6 These challenges could have been foreseen before development and testing began in earnest. 4 7 8 This work aims to identify and fix a number of practical issues of multiple \CFA type-system features and their interactions. 9 In particular, the inclusion of reference types, tuple types, and generic structures together with rich overloading in the language makes the complexity of expression resolution much higher than in other programming languages. 10 I significantly reworked the abstract syntax-tree representation and resolution algorithm to push the \CFA compilation time down to a practical level. 11 The expression-cost system was also revised multiple times to make overload selection more predictable and match programmer's intuition and expectation in the majority of cases. 12 Still, fundamental problems remain and fixing them will require significant changes to the language type-system, possibly from the ground up. 13 14 As per the \CFA project motto ``describe not prescribe,'' \CFA's type system is designed to have a lot of flexibility and give programmers freedom in the usage of overloading and polymorphism. 15 With such a complex type system, it is very difficult (sometimes even impossible) to try to have the compiler accept all the intuitively valid \CFA programs. 16 As has been demonstrated, the \CFA programming language is still far from complete, and the primary future goal is to expand \CFA's type-resolution capability while maintaining, expressibility, decent compile-time, and excellent run-time performance. 17 Stealing some theoretical insights of parametric polymorphism from functional programming, may also prove to be useful. -
doc/theses/fangren_yu_MMath/resolution.tex
r6174ecc rb1b513d 151 151 Specifically, the resolution algorithms used in \CC and Java are greedy, selecting the best match for each subexpression without considering the higher-level ones (bottom-up). 152 152 Therefore, at each resolution step, the arguments are already given unique interpretations, so the ordering only needs to compare different sets of conversion targets (function parameter types) on the same set of input. 153 \begin{cfa}154 @generate a C++ example here@155 156 read more157 \end{cfa}158 153 159 154 In \CFA, trying to use such a system is problematic because of the presence of return-type overloading of functions and variable. -
doc/theses/fangren_yu_MMath/uw-ethesis-frontpgs.tex
r6174ecc rb1b513d 131 131 \begin{center}\textbf{Abstract}\end{center} 132 132 133 Type resolution ... 133 \CFA (C-for-all) is an evolutionary extension of C programming language, which introduces many modern programming language features to C. 134 \CFA has a type system built around parametric polymorphism, and the polymorphic functions are prefixed by a @forall@ declaration of type parameters, giving the language its name. 135 136 This thesis presents a series of work on type resolution in \CFA. Every function, including the built-in C operators, can be overloaded in \CFA, therefore resolving function overloads and generic type parameters is at the heart of \CFA expression analysis. This thesis focuses on the interactions of various \CFA language features such as reference and generic types in type resolution, analyzes the known issues and presents improvements to the type system that fix those problems. Ideas for future work are also given for further improving the consistency of \CFA type system at a language design level. 134 137 135 138 \cleardoublepage -
doc/theses/mike_brooks_MMath/string.tex
r6174ecc rb1b513d 7 7 8 8 \section{String Operations} 9 10 % https://en.wikipedia.org/wiki/Comparison_of_programming_languages_(string_functions) 9 11 10 12 \VRef[Figure]{f:StrApiCompare} shows a general comparison of string APIs for C, \CC, Java and \CFA. … … 23 25 @strlen@ & @length@, @size@ & @length@ & @size@ \\ 24 26 @[ ]@ & @[ ]@ & @charAt@ & @[ ]@ \\ 25 @strncpy@ & @substr@ & @substring@ & @( )@ \\26 @strncpy@ & @replace@ & @replace@ & @ =@ \emph{(on a substring)}\\27 @strncpy@ & @substr@ & @substring@ & @( )@ RHS @=@ \\ 28 @strncpy@ & @replace@ & @replace@ & @( )@ LHS @=@ \\ 27 29 @strstr@ & @find@ & @indexOf@ & @find@ \\ 28 30 @strcspn@ & @find_first_of@ & @matches@ & @include@ \\ … … 62 64 \begin{cquote} 63 65 \sf 64 \begin{tabular}{@{}rrrr rl@{}}65 \small\tt a & \small\tt b & \small\tt c & \small\tt d & \small\tt e\\66 \begin{tabular}{@{}rrrrll@{}} 67 \small\tt "a & \small\tt b & \small\tt c & \small\tt d & \small\tt e" \\ 66 68 0 & 1 & 2 & 3 & 4 & left to right index \\ 67 69 -5 & -4 & -3 & -2 & -1 & right to left index … … 72 74 \begin{cfa} 73 75 #include @<string.hfa>@ 74 @string@ s = "abcde", name = "MIKE", digit , alpha, punctuation, ifstmt;76 @string@ s = "abcde", name = "MIKE", digit = "0123456789"; 75 77 const char cs[] = "abc"; 76 78 int i; 77 digit = "0123456789"; 78 punctuation = "().,"; 79 ifstmt = "IF (A > B) {"; 80 \end{cfa} 81 Note, the include file @string.hfa@ to access type @string@. 79 \end{cfa} 80 Note, the include file @<string.hfa>@ to access type @string@. 82 81 83 82 … … 394 393 Extending the pattern to a regular expression is a possible extension. 395 394 396 397 \subsection{Searching} 398 399 The @index@ operation 400 \begin{cfa} 401 int index( const string & key, int start = 1, occurrence occ = first ); 402 \end{cfa} 403 returns the position of the first or last occurrence of the @key@ (depending on the occurrence indicator @occ@ that is either @first@ or @last@) in the current string starting the search at position @start@. 404 If the @key@ does not appear in the current string, the length of the current string plus one is returned. 405 %If the @key@ has zero length, the value 1 is returned regardless of what the current string contains. 406 A negative starting position is a specification from the right end of the string. 395 The replace operation returns a string in which all occurrences of a substring are replaced by another string. 407 396 \begin{cquote} 408 397 \setlength{\tabcolsep}{15pt} 409 398 \begin{tabular}{@{}l|l@{}} 410 399 \begin{cfa} 411 i = find( digit, "567" ); 412 i = find( digit, "567", 7 ); 413 i = digit.index( "567", -1, last ); 414 i = name.index( "E", 5, last ); 415 \end{cfa} 416 & 417 \begin{cfa} 400 s = replace( "PETER", "E", "XX" ); 401 s = replace( "PETER", "ET", "XX" ); 402 s = replace( "PETER", "W", "XX" ); 403 \end{cfa} 404 & 405 \begin{cfa} 406 "PXXTXXR" 407 "PXXER" 408 "PETER" 409 \end{cfa} 410 \end{tabular} 411 \end{cquote} 412 The replacement is done left-to-right and substituted text is not examined for replacement. 413 414 415 \subsection{Searching} 416 417 The find operation returns the position of the first occurrence of a key string in a string. 418 If the key does not appear in the current string, the length of the current string plus one is returned. 419 \begin{cquote} 420 \setlength{\tabcolsep}{15pt} 421 \begin{tabular}{@{}l|l@{}} 422 \begin{cfa} 423 i = find( digit, '3' ); 424 i = "45" ^ digit; // python style "45" in digit 425 string x = "567"; 426 i = find( digit, x ); 427 \end{cfa} 428 & 429 \begin{cfa} 430 3 431 4 432 418 433 5 419 10 420 421 422 \end{cfa} 423 \end{tabular} 424 \end{cquote} 425 The next two string operations test a string to see if it is or is not composed completely of a particular class of characters. 426 For example, are the characters of a string all alphabetic or all numeric? 427 Use of these operations involves a two step operation. 428 First, it is necessary to create an instance of type @strmask@ and initialize it to a string containing the characters of the particular character class, as in: 429 \begin{cfa} 430 strmask digitmask = digit; 431 strmask alphamask = string( "abcdefghijklmnopqrstuvwxyz" ); 432 \end{cfa} 433 Second, the character mask is used in the functions @include@ and @exclude@ to check a string for compliance of its characters with the characters indicated by the mask. 434 435 The @include@ operation 436 \begin{cfa} 437 int include( const strmask &, int = 1, occurrence occ = first ); 438 \end{cfa} 439 returns the position of the first or last character (depending on the occurrence indicator, which is either @first@ or @last@) in the current string that does not appear in the @mask@ starting the search at position @start@; 440 hence it skips over characters in the current string that are included (in) the @mask@. 441 The characters in the current string do not have to be in the same order as the @mask@. 442 If all the characters in the current string appear in the @mask@, the length of the current string plus one is returned, regardless of which occurrence is being searched for. 443 A negative starting position is a specification from the right end of the string. 444 \begin{cfa} 445 i = name.include( digitmask ); $\C{// i is assigned 1}$ 446 i = name.include( alphamask ); $\C{// i is assigned 6}$ 447 \end{cfa} 448 449 The @exclude@ operation 450 \begin{cfa} 451 int exclude( string &mask, int start = 1, occurrence occ = first ) 452 \end{cfa} 453 returns the position of the first or last character (depending on the occurrence indicator, which is either @first@ or @last@) in the current string that does appear in the @mask@ string starting the search at position @start@; 454 hence it skips over characters in the current string that are excluded from (not in) in the @mask@ string. 455 The characters in the current string do not have to be in the same order as the @mask@ string. 456 If all the characters in the current string do NOT appear in the @mask@ string, the length of the current string plus one is returned, regardless of which occurrence is being searched for. 457 A negative starting position is a specification from the right end of the string. 458 \begin{cfa} 459 i = name.exclude( digitmask ); $\C{// i is assigned 6}$ 460 i = ifstmt.exclude( strmask( punctuation ) ); $\C{// i is assigned 4}$ 461 \end{cfa} 462 463 The @includeStr@ operation: 464 \begin{cfa} 465 string includeStr( strmask &mask, int start = 1, occurrence occ = first ) 466 \end{cfa} 467 returns the longest substring of leading or trailing characters (depending on the occurrence indicator, which is either @first@ or @last@) of the current string that ARE included in the @mask@ string starting the search at position @start@. 468 A negative starting position is a specification from the right end of the string. 469 \begin{cfa} 470 s = name.includeStr( alphamask ); $\C{// s is assigned "MIKE"}$ 471 s = ifstmt.includeStr( alphamask ); $\C{// s is assigned "IF"}$ 472 s = name.includeStr( digitmask ); $\C{// s is assigned ""}$ 473 \end{cfa} 474 475 The @excludeStr@ operation: 476 \begin{cfa} 477 string excludeStr( strmask &mask, int start = 1, occurrence = first ) 478 \end{cfa} 479 returns the longest substring of leading or trailing characters (depending on the occurrence indicator, which is either @first@ or @last@) of the current string that are excluded (NOT) in the @mask@ string starting the search at position @start@. 480 A negative starting position is a specification from the right end of the string. 481 \begin{cfa} 482 s = name.excludeStr( digitmask); $\C{// s is assigned "MIKE"}$ 483 s = ifstmt.excludeStr( strmask( punctuation ) ); $\C{// s is assigned "IF "}$ 484 s = name.excludeStr( alphamask); $\C{// s is assigned ""}$ 485 \end{cfa} 486 487 488 \subsection{Miscellaneous} 489 490 The @trim@ operation 491 \begin{cfa} 492 string trim( string &mask, occurrence occ = first ) 493 \end{cfa} 494 returns a string in that is the longest substring of leading or trailing characters (depending on the occurrence indicator, which is either @first@ or @last@) which ARE included in the @mask@ are removed. 495 \begin{cfa} 496 // remove leading blanks 497 s = string( " ABC" ).trim( " " ); $\C{// s is assigned "ABC",}$ 498 // remove trailing blanks 499 s = string( "ABC " ).trim( " ", last ); $\C{// s is assigned "ABC",}$ 500 \end{cfa} 501 502 The @translate@ operation 503 \begin{cfa} 504 string translate( string &from, string &to ) 505 \end{cfa} 506 returns a string that is the same length as the original string in which all occurrences of the characters that appear in the @from@ string have been translated into their corresponding character in the @to@ string. 507 Translation is done on a character by character basis between the @from@ and @to@ strings; hence these two strings must be the same length. 508 If a character in the original string does not appear in the @from@ string, then it simply appears as is in the resulting string. 509 \begin{cfa} 510 // upper to lower case 511 name = name.translate( "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz" ); 512 // name is assigned "name" 513 s = ifstmt.translate( "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz" ); 514 // ifstmt is assigned "if (a > b) {" 515 // lower to upper case 516 name = name.translate( "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ); 517 // name is assigned "MIKE" 518 \end{cfa} 519 520 The @replace@ operation 521 \begin{cfa} 522 string replace( string &from, string &to ) 523 \end{cfa} 524 returns a string in which all occurrences of the @from@ string in the current string have been replaced by the @to@ string. 525 \begin{cfa} 526 s = name.replace( "E", "XX" ); $\C{// s is assigned "PXXTXXR"}$ 527 \end{cfa} 528 The replacement is done left-to-right. 529 When an instance of the @from@ string is found and changed to the @to@ string, it is NOT examined again for further replacement. 434 \end{cfa} 435 \end{tabular} 436 \end{cquote} 437 The character-class operations indicates if a string is composed completely of a particular class of characters, \eg, alphabetic, numeric, vowels, \etc. 438 \begin{cquote} 439 \setlength{\tabcolsep}{15pt} 440 \begin{tabular}{@{}l|l@{}} 441 \begin{cfa} 442 charclass vowels{ "aeiouy" }; 443 i = include( "aaeiuyoo", vowels ); 444 i = include( "aabiuyoo", vowels ); 445 \end{cfa} 446 & 447 \begin{cfa} 448 449 8 // compliant 450 2 // b non-compliant 451 \end{cfa} 452 \end{tabular} 453 \end{cquote} 454 @vowels@ defines a character class and function @include@ checks if all characters in the string are included in the class (compliance). 455 The position of the last character plus 1 is return if the string is compliant or the position of the first non-compliant character. 456 There is no relationship between the order of characters in the two strings. 457 Function @exclude@ is the reverse of @include@, checking if all characters in the string are excluded from the class (compliance). 458 \begin{cquote} 459 \setlength{\tabcolsep}{15pt} 460 \begin{tabular}{@{}l|l@{}} 461 \begin{cfa} 462 i = exclude( "cdbfghmk", vowels ); 463 i = exclude( "cdyfghmk", vowels ); 464 \end{cfa} 465 & 466 \begin{cfa} 467 8 // compliant 468 2 // y non-compliant 469 \end{cfa} 470 \end{tabular} 471 \end{cquote} 472 Both forms can return the longest substring of compliant characters. 473 \begin{cquote} 474 \setlength{\tabcolsep}{15pt} 475 \begin{tabular}{@{}l|l@{}} 476 \begin{cfa} 477 s = include( "aaeiuyoo", vowels ); 478 s = include( "aabiuyoo", vowels ); 479 s = exclude( "cdbfghmk", vowels ); 480 s = exclude( "cdyfghmk", vowels ); 481 \end{cfa} 482 & 483 \begin{cfa} 484 "aaeiuyoo" 485 "aa" 486 "cdbfghmk" 487 "cd" 488 \end{cfa} 489 \end{tabular} 490 \end{cquote} 491 492 The test operation checks if each character in a string is in one of the C character classes. 493 \begin{cquote} 494 \setlength{\tabcolsep}{15pt} 495 \begin{tabular}{@{}l|l@{}} 496 \begin{cfa} 497 i = test( "1FeC34aB", @isxdigit@ ); 498 i = test( ".,;'!\"", @ispunct@ ); 499 i = test( "XXXx", @isupper@ ); 500 \end{cfa} 501 & 502 \begin{cfa} 503 8 // compliant 504 6 // compliant 505 3 // non-compliant 506 \end{cfa} 507 \end{tabular} 508 \end{cquote} 509 The position of the last character plus 1 is return if the string is compliant or the position of the first non-compliant character. 510 511 Combining substring and search allows actions like trimming whitespace from the start of a line. 512 \begin{cquote} 513 \setlength{\tabcolsep}{15pt} 514 \begin{tabular}{@{}l|l@{}} 515 \begin{cfa} 516 string line = " \t xxx yyy zzz"; 517 string trim = line( test( line, isspace ) ); 518 \end{cfa} 519 & 520 \begin{cfa} 521 522 "xxx yyy zzz" 523 \end{cfa} 524 \end{tabular} 525 \end{cquote} 526 527 The translate operation returns a string with each character transformed by one of the C character transformation functions. 528 \begin{cquote} 529 \setlength{\tabcolsep}{15pt} 530 \begin{tabular}{@{}l|l@{}} 531 \begin{cfa} 532 s = translate( "abc", @toupper@ ); 533 s = translate( "ABC", @tolower@ ); 534 int tospace( int c ) { return isspace( c ) ? ' ' : c; } 535 s = translate( "X X\tX\nX", @tospace@ ); 536 \end{cfa} 537 & 538 \begin{cfa} 539 "ABC" 540 "abc" 541 542 "X X X X" 543 \end{cfa} 544 \end{tabular} 545 \end{cquote} 530 546 531 547 -
libcfa/src/collections/string.cfa
r6174ecc rb1b513d 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Apr 5 15:18:30 202513 // Update Count : 3 1812 // Last Modified On : Wed Apr 9 22:27:40 2025 13 // Update Count : 368 14 14 // 15 15 … … 295 295 bool ?<? ( const char * s1, const string & s2 ) { return s1 < *s2.inner; } 296 296 297 298 ////////////////////////////////////////////////////////299 // Getter300 301 size_t len( const string & s ) {302 return len( *s.inner );303 }304 305 297 //////////////////////////////////////////////////////// 306 298 // Concatenation … … 424 416 } 425 417 426 int find( const string & s, size_t start, size_t len, const string & key, size_t kstart, size_t klen ) {418 size_t find( const string & s, size_t start, size_t len, const string & key, size_t kstart, size_t klen ) { 427 419 if ( start < 0 ) { start += len( s ); } 428 420 if ( len < 0 ) { len = -len; start -= len; } … … 434 426 if ( kstart >= len( key ) ) return 0; 435 427 if ( kstart + klen > len( key ) ) klen = len( key ) - kstart; 436 428 437 429 return findFrom( *s.inner, start, *key.inner ); 438 430 } 439 431 440 int find( const string & s, char key ) {432 size_t find( const string & s, char key ) { 441 433 return find( *s.inner, key ); 442 434 } 443 435 444 int find( const string & s, const string & key ) {436 size_t find( const string & s, const string & key ) { 445 437 return find( *s.inner, *key.inner ); 446 438 } 447 439 448 int find( const string & s, const char * key ) {440 size_t find( const string & s, const char * key ) { 449 441 return find( *s.inner, key ); 450 442 } 451 443 452 int find( const string & s, const char * key, size_t keysize ) {444 size_t find( const string & s, const char * key, size_t keysize ) { 453 445 return find( *s.inner, key, keysize ); 454 446 } 455 447 456 int find( const string & s, size_t start, char key ) {448 size_t find( const string & s, size_t start, char key ) { 457 449 return findFrom( *s.inner, start, key ); 458 450 } 459 451 460 int find( const string & s, size_t start, const char * key ) {452 size_t find( const string & s, size_t start, const char * key ) { 461 453 return findFrom( *s.inner, start, key ); 462 454 } 463 455 464 int find( const string & s, size_t start, const char * key, size_t keysize ) {456 size_t find( const string & s, size_t start, const char * key, size_t keysize ) { 465 457 return findFrom( *s.inner, start, key, keysize ); 466 458 } … … 527 519 } 528 520 529 530 int exclude( const string & s, const charclass & mask ) { 521 size_t exclude( const string & s, const charclass & mask ) { 531 522 return exclude( *s.inner, *mask.inner ); 532 523 } 533 /* 534 StrSlice exclude( string & s, const charclass & mask ) { 535 } 536 */ 537 538 int include( const string & s, const charclass & mask ) { 524 525 size_t include( const string & s, const charclass & mask ) { 539 526 return include( *s.inner, *mask.inner ); 540 527 } 541 528 542 /* 543 StrSlice include( string & s, const charclass & mask ) { 544 } 545 */ 529 size_t test( const string & s, int (*f)( int ) ) { 530 size_t l = len( s ); 531 for ( i; l ) { 532 if ( ! f( s[i] ) ) return i; 533 } // for 534 return l; 535 } 536 537 string replace( string & s, const string & from, const string & to ) { 538 ssize_t pos; 539 string r; 540 541 pos = find( s, from ); 542 if ( pos < len( s ) ) { 543 r = s( 0, pos ) + to + replace( s( pos + (ssize_t)len( from ) ), from, to ); 544 string front = s( 0, pos ); 545 string back = s( pos + (ssize_t)len( from ) ); 546 r = front + to + replace( back, from, to ); 547 } else { 548 r = s; 549 } // if 550 return r; 551 } 552 553 string translate( const string & s, int (*f)( int ) ) { 554 string r = s; 555 size_t l = len( r ); 556 for ( i; l ) { 557 r[i] = (char)f( r[i] ); 558 } // for 559 return r; 560 } -
libcfa/src/collections/string.hfa
r6174ecc rb1b513d 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Apr 5 15:16:23202513 // Update Count : 18012 // Last Modified On : Wed Apr 9 22:27:41 2025 13 // Update Count : 259 14 14 // 15 15 … … 17 17 18 18 #include <fstream.hfa> 19 20 21 // in string_res.hfa 22 struct string_res; 23 struct charclass_res; 19 #include <string_res.hfa> 24 20 25 21 struct string { … … 28 24 29 25 // Getters 26 static inline size_t len( const string & s ) { return len( *s.inner ); } 30 27 static inline size_t len( const char * cs ) { return strlen( cs ); }; 31 size_t len( const string & s );32 28 static inline size_t strlen( const string & s ) { return len( s ); } 33 29 … … 215 211 bool contains( const string & s, char ch ); // single character 216 212 217 int find( const string & s, char key ); 218 static inline int ?^? ( const string & s, char key ) { return find( s, key ); } 219 int find( const string & s, const char * key ); 220 static inline int ?^? ( const string & s, const char * key ) { return find( s, key ); } 221 int find( const string & s, const string & key ); 222 static inline int ?^? ( const string & s, const string & key ) { return find( s, key ); } 223 int find( const string & s, const char * key, size_t keysize ); 224 225 int find( const string & s, size_t start, char key ); 226 int find( const string & s, size_t start, const string & key ); 227 int find( const string & s, size_t start, const char * key ); 228 int find( const string & s, size_t start, const char * key, size_t keysize ); 213 //int find( const string & s, size_t start, size_t len, const string & key, size_t kstart, size_t klen ); 214 size_t find$( const string_res & s, size_t start, size_t len, const string & key_res, size_t kstart, size_t klen ); 215 216 size_t find( const string & s, char key ); 217 size_t find( const string & s, const char * key ); 218 size_t find( const string & s, const string & key ); 219 size_t find( const string & s, const char * key, size_t keysize ); 220 221 size_t find( const string & s, size_t start, char key ); 222 size_t find( const string & s, size_t start, const string & key ); 223 size_t find( const string & s, size_t start, const char * key ); 224 size_t find( const string & s, size_t start, const char * key, size_t keysize ); 225 static inline ?^?( const string & key, const string & s ) { return find( s, key ); } 226 static inline ?^?( const char * key, const string & s ) { return find( s, key ); } 229 227 230 228 bool includes( const string & s, const string & mask ); … … 241 239 242 240 // Slicing 243 string ?()( string & s, ssize_t start, ssize_t len ); // TODO const? 241 string ?()( string & s, ssize_t start, ssize_t len ); 242 static inline string ?()( const string & s, ssize_t start, ssize_t len ) { string & w = (string &)s; return w( start, len ); } // FIX ME 244 243 string ?()( string & s, ssize_t start ); 244 static inline string ?()( const string & s, ssize_t start ) { string & w = (string &)s; return w( start ); } // FIX ME 245 245 static inline string ?()( string & s, char m ) { return s( find( s, m ), 1 )`share; } 246 static inline string ?()( const string & s, char m ) { string & w = (string &)s; return w( find( s, m ), 1 )`share; } // FIX ME 246 247 static inline string ?()( string & s, const char * m ) { return s( find( s, m ), len( m ) )`share; } 248 static inline string ?()( const string & s, const char * m ) { string & w = (string &)s; return w( find( s, m ), len( m ) )`share; } // FIX ME 247 249 static inline string ?()( string & s, const string & m ) { return s( find( s, m ), len( m ) )`share; } 248 249 // Modifiers 250 void padStart( string & s, size_t n ); 251 void padStart( string & s, size_t n, char padding ); 252 void padEnd( string & s, size_t n ); 253 void padEnd( string & s, size_t n, char padding ); 254 250 static inline string ?()( const string & s, const string & m ) { string & w = (string &)s; return w( find( s, m ), len( m ) )`share; } // FIX ME 255 251 256 252 struct charclass { … … 267 263 void ^?{}( charclass & ); 268 264 269 int include( const string & s, const charclass & mask ); 270 271 int exclude( const string & s, const charclass & mask ); 272 273 /* 274 What to do with? 275 StrRet include( string & s, const charclass & mask ); 276 StrRet exclude( string & s, const charclass & mask ); 277 */ 265 size_t include( const string & s, const charclass & mask ); 266 static inline size_t include( const char * s, const charclass & mask ) { string temp = s; return include( temp, mask ); } 267 static inline string include( const string & s, const charclass & mask ) { ssize_t i = include( s, mask ); return s( 0, i )`share; } 268 static inline string include( const char * s, const charclass & mask ) { string temp = s; ssize_t i = include( temp, mask ); return temp( 0, i ); } 269 270 size_t exclude( const string & s, const charclass & mask ); 271 static inline size_t exclude( const char * s, const charclass & mask ) { string temp = s; return exclude( temp, mask ); } 272 static inline string exclude( const string & s, const charclass & mask ) { ssize_t i = exclude( s, mask ); return s( 0, i )`share; } 273 static inline string exclude( const char * s, const charclass & mask ) { string temp = s; ssize_t i = exclude( temp, mask ); return temp( 0, i ); } 274 275 size_t test( const string & s, int (*f)( int ) ); 276 static inline size_t test( const char * c, int (*f)( int ) ) { 277 const string S = c; 278 return test( S, f ); 279 } 280 281 string replace( string & s, const string & from, const string & to ); 282 static inline string replace( const char * s, const char * from, const char * to ) { 283 string S = s, From = from, To = to; 284 return replace( S, From, To ); 285 } 286 static inline string replace( string & s, const char * from, const char * to ) { 287 string From = from, To = to; 288 return replace( s, From, To ); 289 } 290 static inline string replace( string & s, const char * from, const string & to ) { 291 string From = from; 292 return replace( s, From, to ); 293 } 294 static inline string replace( string & s, string & from, const char * to ) { 295 string To = to; 296 return replace( s, from, To ); 297 } 298 299 string translate( const string & s, int (*f)( int ) ); 300 static inline string translate( const char * c, int (*f)( int ) ) { 301 const string S = c; 302 return translate( S, f ); 303 } -
libcfa/src/collections/string_res.cfa
r6174ecc rb1b513d 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Apr 6 07:38:02202513 // Update Count : 1 1112 // Last Modified On : Wed Apr 9 08:44:17 2025 13 // Update Count : 128 14 14 // 15 15 … … 190 190 const char * DEBUG_string_heap_start( VbyteHeap * heap ) { 191 191 return heap->StartVbyte; 192 }193 194 // Returns the size of the string in bytes195 size_t len(const string_res & s) with(s) {196 return Handle.lnth;197 192 } 198 193 … … 756 751 } 757 752 758 int find(const string_res & s, char search) { 753 // int find$( const string_res & s, ssize_t start, ssize_t len, const string_res & k, ssize_t kstart, ssize_t klen ) { 754 // if ( start < 0 ) start = s.Handle.lnth + start; // adjust negative starting locations 755 // if ( kstart < 0 ) kstart = k.Handle.lnth + kstart; 756 757 // if ( start + len > s.Handle.lnth ) return start + 1; // cannot be there 758 // if ( kstart + len > k.Handle.lnth ) return start + 1; 759 // if ( klen > len ) return start + 1; 760 761 // int i, r; 762 763 // for ( i = max( start, 1 ); ; i += 1 ) { 764 // if ( i > s.Handle.lnth - k.Handle.lnth + 1 ) { 765 // r = s.Handle.lnth + 1; 766 // break; 767 // } // exit 768 // if ( HeapArea->ByteCmp( s.Handle.s, i, k.Handle.lnth, k.Handle.s, 1, k.Handle.lnth ) == 0 ) { 769 // r = i; 770 // break; 771 // } // exit 772 // } // for 773 // return r; 774 // } 775 776 int find( const string_res & s, char search ) { 759 777 return findFrom(s, 0, search); 760 778 } 761 779 762 int findFrom( const string_res & s, size_t fromPos, char search) {780 int findFrom( const string_res & s, size_t fromPos, char search ) { 763 781 // FIXME: This paricular overload (find of single char) is optimized to use memchr. 764 782 // The general overload (find of string, memchr applying to its first character) and `contains` should be adjusted to match. -
libcfa/src/collections/string_res.hfa
r6174ecc rb1b513d 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Apr 6 07:35:44202513 // Update Count : 7 012 // Last Modified On : Wed Apr 9 15:16:29 2025 13 // Update Count : 76 14 14 // 15 15 … … 70 70 71 71 // Getters 72 s ize_t len( const string_res & s);72 static inline size_t len( const string_res & s ) { return s.Handle.lnth; } 73 73 74 74 // Constructors, Assignment Operators, Destructor … … 220 220 bool contains( const string_res & s, char ch); // single character 221 221 222 int find$( const string_res & s, ssize_t start, ssize_t len, const string_res & key, ssize_t kstart, ssize_t klen ); 223 222 224 int find( const string_res & s, char search); 223 225 int find( const string_res & s, const string_res & search); … … 245 247 int exclude( const string_res & s, const charclass_res & mask); 246 248 247 // Modifiers248 void padStart(string_res & s, size_t n);249 void padStart(string_res & s, size_t n, char padding);250 void padEnd(string_res & s, size_t n);251 void padEnd(string_res &s, size_t n, char padding);252 -
tests/collections/.expect/string-api-coverage.txt
r6174ecc rb1b513d 85 85 true false true false true true true false true false 86 86 3 0 0 11 26 0 87 abc abcdefghijk abcdefghijklmnopqrstuvwxyz -
tests/collections/string-api-coverage.cfa
r6174ecc rb1b513d 392 392 393 393 sout 394 | include( alphabet, cc_cba ) // 3 395 | exclude( alphabet, cc_cba ) // 0 396 | include( alphabet, cc_onml ) // 0 397 | exclude( alphabet, cc_onml ) // 11 398 | include( alphabet, cc_alphabet ) // 26 399 | exclude( alphabet, cc_alphabet ); // 0 394 | (return size_t)include( alphabet, cc_cba ) // 3 395 | (return size_t)exclude( alphabet, cc_cba ) // 0 396 | (return size_t)include( alphabet, cc_onml ) // 0 397 | (return size_t)exclude( alphabet, cc_onml ) // 11 398 | (return size_t)include( alphabet, cc_alphabet ) // 26 399 | (return size_t)exclude( alphabet, cc_alphabet ); // 0 400 401 sout 402 | (return string)include( alphabet, cc_cba ) // "abc" 403 | (return string)exclude( alphabet, cc_cba ) // "" 404 | (return string)include( alphabet, cc_onml ) // "" 405 | (return string)exclude( alphabet, cc_onml ) // "abcdefghijk" 406 | (return string)include( alphabet, cc_alphabet ) // "abcdefghijklmnopqrstuvwxyz" 407 | (return string)exclude( alphabet, cc_alphabet ); // "" 400 408 } 401
Note:
See TracChangeset
for help on using the changeset viewer.