From 7eb1f4934ca6e3afac4c075664bc78c0e4be6e69 Mon Sep 17 00:00:00 2001 From: mtardy Date: Wed, 19 Aug 2020 10:47:11 +0200 Subject: [PATCH] Add '*' operator for string multiplication --- object.c | 16 ++++++++++++++++ parse.leg | 30 ++++++++++++++++++++++-------- test-strings.txt | 6 +++++- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/object.c b/object.c index c45339f..c99ab18 100644 --- a/object.c +++ b/object.c @@ -230,6 +230,22 @@ oop string_concat(oop str1, oop str2) return newString; } +oop string_mul(oop str, oop factor) +{ + ssize_t len = string_size(str) * getInteger(factor); + if (len < 0) len = 0; + char *concat = memcheck(malloc(sizeof(char) * len + 1)); + for (int i=0; i < getInteger(factor); ++i) { + memcpy(concat + (i * string_size(str)), get(str, String, value), string_size(str)); + } + concat[len]= '\0'; + oop newString = memcheck(malloc(sizeof(union object))); + newString->type = String; + newString->String.value = concat; + newString->String.size = len; + return newString; +} + oop makeSymbol(char *name) { oop newSymb = memcheck(malloc(sizeof(union object))); diff --git a/parse.leg b/parse.leg index afb187a..f356697 100644 --- a/parse.leg +++ b/parse.leg @@ -7,9 +7,8 @@ */ #define DO_PROTOS() \ - _DO(If) _DO(While) _DO(Do) _DO(For) _DO(Switch) _DO(Call) _DO(Invoke) _DO(Func) _DO(Block) _DO(Declaration) \ - _DO(Assign) _DO(AssignAdd) _DO(AssignSub) _DO(AssignMul) _DO(AssignDiv) _DO(AssignMod) \ - _DO(AssignBitor) _DO(AssignBitxor) _DO(AssignBitand) _DO(AssignShleft) _DO(AssignShright) \ + _DO(If) _DO(While) _DO(Do) _DO(For) _DO(Switch) _DO(Call) _DO(Invoke) _DO(Func) _DO(Block) \ + _DO(Declaration) _DO(Assign) \ _DO(Map) _DO(Symbol) _DO(Integer) _DO(String) \ _DO(Logor) _DO(Logand) _DO(Bitor) _DO(Bitxor) _DO(Bitand) \ _DO(Equal) _DO(Noteq) _DO(Less) _DO(Lesseq) _DO(Greater) _DO(Greatereq) _DO(Shleft) _DO(Shright) \ @@ -19,10 +18,6 @@ _DO(PreDecVariable) _DO(PreDecMember) _DO(PreDecIndex) \ _DO(PostDecVariable) _DO(PostDecMember) _DO(PostDecIndex) \ _DO(GetVariable) _DO(GetMember) _DO(SetMember) _DO(GetIndex) _DO(SetIndex) \ - _DO(SetMemberAdd) _DO(SetMemberSub) _DO(SetMemberMul) _DO(SetMemberDiv) _DO(SetMemberMod) \ - _DO(SetMemberBitor) _DO(SetMemberBitxor) _DO(SetMemberBitand) _DO(SetMemberShleft) _DO(SetMemberShright) \ - _DO(SetIndexAdd) _DO(SetIndexSub) _DO(SetIndexMul) _DO(SetIndexDiv) _DO(SetIndexMod) \ - _DO(SetIndexBitor) _DO(SetIndexBitxor) _DO(SetIndexBitand) _DO(SetIndexShleft) _DO(SetIndexShright) \ _DO(Return) _DO(Break) _DO(Continue) \ _DO(Quasiquote) _DO(Unquote) @@ -903,6 +898,20 @@ oop addOperation(oop lhs, oop rhs) } } +oop mulOperation(oop lhs, oop rhs) +{ + if (getType(lhs) == Integer && getType(rhs) == Integer) { + return makeInteger(getInteger(lhs) * getInteger(rhs)); + } else if (getType(lhs) == String && getType(rhs) == Integer) { + return string_mul(lhs, rhs); + } else if (getType(lhs) == Integer && getType(rhs) == String) { + return string_mul(rhs, lhs); + } else { + fprintf(stderr, "\nmultiplication between two incompatible types\n"); + exit(1); + } +} + oop expandUnquotes(oop scope, oop obj) { obj = clone(obj); @@ -1462,7 +1471,12 @@ oop eval(oop scope, oop ast) return addOperation(lhs, rhs); } BINARY(Sub, - ); - BINARY(Mul, * ); +// BINARY(Mul, * ); + case t_Mul: { + oop lhs = eval(scope, map_get(ast, lhs_symbol)); + oop rhs = eval(scope, map_get(ast, rhs_symbol)); + return mulOperation(lhs, rhs); + } BINARY(Div, / ); BINARY(Mod, % ); # undef BINARY diff --git a/test-strings.txt b/test-strings.txt index 533d57a..89ae70d 100644 --- a/test-strings.txt +++ b/test-strings.txt @@ -7,4 +7,8 @@ length(str) new = str + wrl print("length is: ", length(new), "\n"); a = { str1: "hello", str2: " japan!" } -a[#str1]+=a[#str2] \ No newline at end of file +a[#str1]+=a[#str2] +str * 10 +str * -1 +str * str +str[0:5]="ok" \ No newline at end of file