Skip to content

Commit 37ed6c8

Browse files
committed
optimized some BASIC string expressions
1 parent 52559af commit 37ed6c8

File tree

5 files changed

+81
-3
lines changed

5 files changed

+81
-3
lines changed

Changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ Version 6.1.6
33
- Implemented flush() for FATFS files (thanks to Ada)
44
- Improved some error messages
55
- In C++ output, treat unknown types in prints as generic
6+
- Optimized a few BASIC string expressions
67
- Revised BASIC use of + operator on strings
78

89
Version 6.1.5

ast.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,9 +519,63 @@ AstStringLen(AST *list)
519519
}
520520
list = list->right;
521521
}
522+
if (list && list->kind == AST_STRING) {
523+
len += strlen(list->d.string);
524+
}
522525
return len;
523526
}
524527

528+
static char *
529+
CopyString(char *p, AST *list)
530+
{
531+
list = list->left;
532+
while (list && list->kind == AST_EXPRLIST) {
533+
if (!list->left) continue;
534+
if (list->left->kind == AST_STRING) {
535+
strcpy(p, list->left->d.string);
536+
p += strlen(list->left->d.string);
537+
} else {
538+
*p++ = list->left->d.ival;
539+
}
540+
list = list->right;
541+
}
542+
if (list && list->kind == AST_STRING) {
543+
strcpy(p, list->d.string);
544+
p += strlen(list->d.string);
545+
}
546+
return p;
547+
}
548+
549+
/* merge two AST string pointers */
550+
AST *
551+
AstMergeStrings(AST *left, AST *right)
552+
{
553+
int newLen = 1;
554+
if (left) {
555+
if (left->kind != AST_STRINGPTR) {
556+
ERROR(left, "Internal errors, expected string");
557+
return left;
558+
}
559+
newLen += AstStringLen(left);
560+
}
561+
if (right) {
562+
if (right->kind != AST_STRINGPTR) {
563+
ERROR(right, "Internal errors, expected string");
564+
return left;
565+
}
566+
newLen += AstStringLen(right);
567+
}
568+
char *newBuf = malloc(newLen);
569+
char *p = newBuf;
570+
if (left) {
571+
p = CopyString(p, left);
572+
}
573+
if (right) {
574+
p = CopyString(p, right);
575+
}
576+
return AstStringPtr(newBuf);
577+
}
578+
525579
/* return length of an AST list; data is on left, ptr to next on right */
526580
int
527581
AstListLen(AST *list)

ast.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,9 @@ int AstListLen(AST *a);
309309
/* length of an AST stringptr list */
310310
int AstStringLen(AST *a);
311311

312+
/* merge two AST string lists */
313+
AST *AstMergeStrings(AST *lhs, AST *rhs);
314+
312315
/* mark new ASTs to be created to have the same line as AST old */
313316
/* used when we're transforming ASTs */
314317
void AstReportAs(AST *old, ASTReportInfo *save);

frontends/basic/basiclang.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -924,12 +924,25 @@ doBasicTransform(AST **astptr, bool transformFuncall)
924924
case AST_FUNCCALL:
925925
doBasicTransform(&ast->left, transformFuncall);
926926
doBasicTransform(&ast->right, transformFuncall);
927-
if (transformFuncall)
928-
{
927+
if (transformFuncall) {
929928
// the parser treats a(x) as a function call (always), but in
930929
// fact it may be an array reference; change it to one if applicable
931930
adjustFuncCall(ast);
932931
}
932+
// check for some special cases like chr$(65)
933+
if (ast->kind == AST_FUNCCALL && IsIdentifier(ast->left)) {
934+
const char *funcName = GetIdentifierName(ast->left);
935+
if (!strcasecmp(funcName, "chr$")) {
936+
AST *arg = ast->right->left;
937+
if (arg && ast->right->right == NULL && IsConstExpr(arg)) {
938+
int n = EvalConstExpr(arg);
939+
char *s = malloc(2);
940+
s[0] = n;
941+
s[1] = 0;
942+
*ast = *AstStringPtr(s);
943+
}
944+
}
945+
}
933946
break;
934947
case AST_METHODREF:
935948
doBasicTransform(&ast->left, transformFuncall);

frontends/types.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,14 @@ MakeOperatorCall(AST *func, AST *left, AST *right, AST *extraArg)
162162
if (extraArg) {
163163
params = AddToList(params, NewAST(AST_EXPRLIST, extraArg, NULL));
164164
}
165-
call = NewAST(AST_FUNCCALL, func, params);
165+
166+
// do some optimizations on constant values
167+
if (func == string_concat && left && right && left->kind == AST_STRINGPTR && right->kind == AST_STRINGPTR)
168+
{
169+
call = AstMergeStrings(left, right);
170+
} else {
171+
call = NewAST(AST_FUNCCALL, func, params);
172+
}
166173
AstReportDone(&saveinfo);
167174
return call;
168175
}

0 commit comments

Comments
 (0)