Skip to content

Commit 474dbd4

Browse files
committed
convert BASIC LEN() into a keyword operator, so we can compile time optimize when the argument is constant
1 parent 3d4108e commit 474dbd4

File tree

6 files changed

+34
-2
lines changed

6 files changed

+34
-2
lines changed

ast.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,6 +1013,9 @@ static void doASTDump(AST *ast, int indent)
10131013
case K_ASC:
10141014
opString = "asc";
10151015
break;
1016+
case K_LEN:
1017+
opString = "strlen";
1018+
break;
10161019
case K_POWER:
10171020
opString = "power";
10181021
break;

doc/basic.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ if
255255
import
256256
input
257257
integer
258+
len
258259
let
259260
lib
260261
line
@@ -367,7 +368,6 @@ instrrev
367368
lcase$
368369
kill
369370
left$
370-
len
371371
_lockclr
372372
_locknew
373373
_lockrel

frontends/basic/basic.y

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ AdjustParamForByVal(AST *param)
461461
%token BAS_INPUT "input"
462462
%token BAS_CAST_INT "int"
463463
%token BAS_INTEGER_KW "integer"
464+
%token BAS_LEN "len"
464465
%token BAS_LET "let"
465466
%token BAS_LIB "lib"
466467
%token BAS_LINE "line"
@@ -1640,6 +1641,8 @@ unary_op:
16401641
{ $$ = AstOperator(K_ABS, NULL, NULL); }
16411642
| BAS_ASC
16421643
{ $$ = AstOperator(K_ASC, NULL, NULL); }
1644+
| BAS_LEN
1645+
{ $$ = AstOperator(K_LEN, NULL, NULL); }
16431646
| BAS_SQRT
16441647
{ $$ = AstOperator(K_SQRT, NULL, NULL); }
16451648
;

frontends/lexer.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,6 +2318,7 @@ struct reservedword basic_keywords[] = {
23182318
{ "input", BAS_INPUT },
23192319
{ "int", BAS_CAST_INT },
23202320
{ "integer", BAS_INTEGER_KW },
2321+
{ "len", BAS_LEN },
23212322
{ "let", BAS_LET },
23222323
{ "lib", BAS_LIB },
23232324
{ "line", BAS_LINE },

frontends/types.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ static AST *struct_copy;
107107
static AST *struct_memset;
108108
static AST *string_cmp;
109109
static AST *string_concat;
110+
static AST *string_length;
110111

111112
static AST *string_tointeger;
112113
static AST *string_frominteger;
@@ -1127,6 +1128,26 @@ AST *CoerceOperatorTypes(AST *ast, AST *lefttype, AST *righttype)
11271128
}
11281129
}
11291130
return ast_type_long;
1131+
case K_LEN:
1132+
if (!CompatibleTypes(righttype, ast_type_string)) {
1133+
if (curfunc && IsBasicLang(curfunc->language)) {
1134+
ERROR(ast, "expected string argument to LEN");
1135+
} else {
1136+
ERROR(ast, "expected string argument to __builtin_strlen");
1137+
}
1138+
} else {
1139+
AST *newast;
1140+
AST *sexpr = ast->right;
1141+
1142+
if (sexpr && sexpr->kind == AST_STRINGPTR) {
1143+
/* the -1 is to remove the trailing 0 */
1144+
newast = AstInteger(AstStringLen(sexpr) - 1);
1145+
} else {
1146+
newast = MakeOperatorCall(string_length, sexpr, NULL, NULL);
1147+
}
1148+
*ast = *newast;
1149+
}
1150+
return ast_type_long;
11301151
case K_BOOL_NOT:
11311152
case K_BOOL_AND:
11321153
case K_BOOL_OR:
@@ -2169,6 +2190,7 @@ InitGlobalFuncs(void)
21692190

21702191
string_cmp = getBasicPrimitive("_string_cmp");
21712192
string_concat = getBasicPrimitive("_string_concat");
2193+
string_length = getBasicPrimitive("__builtin_strlen");
21722194
string_tointeger = getBasicPrimitive("__builtin_atoi");
21732195
string_frominteger = getBasicPrimitive("strint$");
21742196
gc_alloc_managed = getBasicPrimitive("_gc_alloc_managed");

optokens.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ enum OpToken {
4141
K_LEU,
4242
K_GTU,
4343
K_GEU,
44-
K_ASC,
44+
45+
K_ASC, /* BASIC ASC operator */
46+
K_LEN, /* BASIC LEN operator */
47+
4548
K_LIMITMIN_UNS,
4649
K_LIMITMAX_UNS,
4750
K_POWER,

0 commit comments

Comments
 (0)