Browse Source

Add '+' operator for string concatenation

pull/11/head
mtardy 4 years ago
parent
commit
292ad05968
3 changed files with 57 additions and 11 deletions
  1. +15
    -0
      object.c
  2. +32
    -11
      parse.leg
  3. +10
    -0
      test-strings.txt

+ 15
- 0
object.c View File

@ -211,6 +211,21 @@ oop makeString(char *value)
return newString; return newString;
} }
size_t string_size(oop s)
{
return get(s, String, size);
}
oop string_concat(oop str1, oop str2)
{
size_t len = string_size(str1) + string_size(str2);
char *concat = memcheck(malloc(sizeof(char) * len));
memcpy(concat, get(str1, String, value), string_size(str1));
memcpy(concat + string_size(str1), get(str2, String, value), string_size(str2));
// it will strdup concat, is it bad?
return makeString(concat);
}
oop makeSymbol(char *name) oop makeSymbol(char *name)
{ {
oop newSymb = memcheck(malloc(sizeof(union object))); oop newSymb = memcheck(malloc(sizeof(union object)));

+ 32
- 11
parse.leg View File

@ -891,6 +891,18 @@ oop clone(oop obj)
return obj; return obj;
} }
oop addOperation(oop lhs, oop rhs)
{
if (getType(lhs) == Integer && getType(rhs) == Integer) {
return makeInteger(getInteger(lhs) + getInteger(rhs));
} else if (getType(lhs) == String && getType(rhs) == String) {
return string_concat(lhs, rhs);
} else {
fprintf(stderr, "\naddition between two incompatible types\n");
exit(1);
}
}
oop expandUnquotes(oop scope, oop obj) oop expandUnquotes(oop scope, oop obj)
{ {
obj = clone(obj); obj = clone(obj);
@ -982,7 +994,7 @@ oop applyOperator(oop op, oop lhs, oop rhs)
{ {
if (null != op) { assert(is(Symbol, op)); if (null != op) { assert(is(Symbol, op));
switch (get(op, Symbol, prototype)) { switch (get(op, Symbol, prototype)) {
case t_Add: return makeInteger(getInteger(lhs) + getInteger(rhs));
case t_Add: return addOperation(lhs, rhs);
case t_Sub: return makeInteger(getInteger(lhs) - getInteger(rhs)); case t_Sub: return makeInteger(getInteger(lhs) - getInteger(rhs));
case t_Mul: return makeInteger(getInteger(lhs) * getInteger(rhs)); case t_Mul: return makeInteger(getInteger(lhs) * getInteger(rhs));
case t_Div: return makeInteger(getInteger(lhs) / getInteger(rhs)); case t_Div: return makeInteger(getInteger(lhs) / getInteger(rhs));
@ -1201,7 +1213,7 @@ oop eval(oop scope, oop ast)
oop lhs = map_get(ast, lhs_symbol); oop lhs = map_get(ast, lhs_symbol);
oop op = map_get(ast, operator_symbol); oop op = map_get(ast, operator_symbol);
oop rhs = eval(scope, map_get(ast, rhs_symbol)); oop rhs = eval(scope, map_get(ast, rhs_symbol));
if (null != op) rhs= applyOperator(op, getVariable(scope, lhs), rhs);
if (null != op) rhs= applyOperator(op, getVariable(scope, lhs), rhs);
setVariable(scope, lhs, rhs); setVariable(scope, lhs, rhs);
if (is(Function, rhs) && null == get(rhs, Function, name)) { if (is(Function, rhs) && null == get(rhs, Function, name)) {
set(rhs, Function, name, lhs); set(rhs, Function, name, lhs);
@ -1360,7 +1372,7 @@ oop eval(oop scope, oop ast)
oop key = map_get(ast, key_symbol); oop key = map_get(ast, key_symbol);
oop op = map_get(ast, operator_symbol); oop op = map_get(ast, operator_symbol);
oop value = eval(scope, map_get(ast, value_symbol)); oop value = eval(scope, map_get(ast, value_symbol));
if (null != op) value= applyOperator(op, getMember(map, key), value);
if (null != op) value= applyOperator(op, getMember(map, key), value);
if (is(Function, value) && null == get(value, Function, name)) { if (is(Function, value) && null == get(value, Function, name)) {
set(value, Function, name, key); set(value, Function, name, key);
} }
@ -1416,16 +1428,14 @@ oop eval(oop scope, oop ast)
get(map, String, value)[getInteger(key)] = getInteger(value); get(map, String, value)[getInteger(key)] = getInteger(value);
return value; return value;
case Map: case Map:
if (null != op) {
value= applyOperator(op, map_get(map, key), value);
}
if (null != op) value= applyOperator(op, map_get(map, key), value);
return map_set(map, key, value); return map_set(map, key, value);
default: default:
// should it returns null instead? // should it returns null instead?
fprintf(stderr, "\nSetIndex on non Map or String\n"); fprintf(stderr, "\nSetIndex on non Map or String\n");
exit(1); exit(1);
} }
} }
# define SETINDEXOP(OPERATION, OPERATOR) \ # define SETINDEXOP(OPERATION, OPERATOR) \
case t_SetIndex##OPERATION: { \ case t_SetIndex##OPERATION: { \
@ -1471,7 +1481,13 @@ oop eval(oop scope, oop ast)
oop result = makeInteger(getInteger(eval(scope, lhs)) OPERATOR getInteger(rhs)); \ oop result = makeInteger(getInteger(eval(scope, lhs)) OPERATOR getInteger(rhs)); \
return setVariable(scope, lhs, result); \ return setVariable(scope, lhs, result); \
} }
ASSIGNOP(Add, +);
// ASSIGNOP(Add, +);
case t_AssignAdd: {
oop lhs = map_get(ast, lhs_symbol);
oop rhs = eval(scope, map_get(ast, rhs_symbol));
oop result = addOperation(eval(scope, lhs), rhs);
return setVariable(scope, lhs, result);
}
ASSIGNOP(Sub, -); ASSIGNOP(Sub, -);
ASSIGNOP(Mul, *); ASSIGNOP(Mul, *);
ASSIGNOP(Div, /); ASSIGNOP(Div, /);
@ -1485,7 +1501,7 @@ oop eval(oop scope, oop ast)
# define BINARY(NAME, OPERATOR) \ # define BINARY(NAME, OPERATOR) \
case t_##NAME: { \ case t_##NAME: { \
oop lhs = eval(scope, map_get(ast, lhs_symbol)); \ oop lhs = eval(scope, map_get(ast, lhs_symbol)); \
oop rhs = eval(scope ,map_get(ast, rhs_symbol)); \
oop rhs = eval(scope, map_get(ast, rhs_symbol)); \
return makeInteger(getInteger(lhs) OPERATOR getInteger(rhs)); \ return makeInteger(getInteger(lhs) OPERATOR getInteger(rhs)); \
} }
BINARY(Bitor, | ); BINARY(Bitor, | );
@ -1499,7 +1515,12 @@ oop eval(oop scope, oop ast)
BINARY(Greater, > ); BINARY(Greater, > );
BINARY(Shleft, <<); BINARY(Shleft, <<);
BINARY(Shright, >>); BINARY(Shright, >>);
BINARY(Add, + );
// BINARY(Add, + );
case t_Add: {
oop lhs = eval(scope, map_get(ast, lhs_symbol));
oop rhs = eval(scope, map_get(ast, rhs_symbol));
return addOperation(lhs, rhs);
}
BINARY(Sub, - ); BINARY(Sub, - );
BINARY(Mul, * ); BINARY(Mul, * );
BINARY(Div, / ); BINARY(Div, / );
@ -1643,7 +1664,7 @@ oop prim_length(oop params)
if (map_hasIntegerKey(params, 0)) { if (map_hasIntegerKey(params, 0)) {
oop arg= get(params, Map, elements)[0].value; oop arg= get(params, Map, elements)[0].value;
switch (getType(arg)) { switch (getType(arg)) {
case String: return makeInteger(strlen(get(arg, String, value)));
case String: return makeInteger(string_size(arg));
case Symbol: return makeInteger(strlen(get(arg, Symbol, name))); case Symbol: return makeInteger(strlen(get(arg, Symbol, name)));
case Map: return makeInteger(map_size(arg)); case Map: return makeInteger(map_size(arg));
default: break; default: break;

+ 10
- 0
test-strings.txt View File

@ -0,0 +1,10 @@
str = "hello"
wrl = " world!"
str[1]='a'
str[1]
str
length(str)
new = str + wrl
print("length is: ", length(new), "\n");
a = { str1: "hello", str2: " japan!" }
a[#str1]+=a[#str2]

Loading…
Cancel
Save