simon 01/09/13 00:14:26
Modified: . basic_opcodes.ops opcode_table string.c string.h
strnative.c
t test2.pasm
Log:
String substr op; also rearranged "encoding" to be a vtable pointer, not
an array index. Haven't changed docs to reflect this, oops.
Simon
Revision Changes Path
1.9 +6 -0 parrot/basic_opcodes.ops
Index: basic_opcodes.ops
===================================================================
RCS file: /home/perlcvs/parrot/basic_opcodes.ops,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -w -r1.8 -r1.9
--- basic_opcodes.ops 2001/09/12 18:39:12 1.8
+++ basic_opcodes.ops 2001/09/13 07:14:23 1.9
@@ -326,6 +326,12 @@
string_chopn(STR_REG(P1), P2);
}
+// SUBSTR Sx, Sx, Ix, Ix
+AUTO_OP substr_s_s_i {
+ STRING *s = string_substr(STR_REG(P2), INT_REG(P3), INT_REG(P4), &STR_REG(P1));
+ STR_REG(P1) = s;
+}
+
// NOOP
AUTO_OP noop {
}
1.10 +1 -0 parrot/opcode_table
Index: opcode_table
===================================================================
RCS file: /home/perlcvs/parrot/opcode_table,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -w -r1.9 -r1.10
--- opcode_table 2001/09/12 18:39:12 1.9
+++ opcode_table 2001/09/13 07:14:24 1.10
@@ -56,6 +56,7 @@
print_s 1 S
length_i_s 2 I S
chopn_s_ic 2 S i
+substr_s_s_i 4 S S I I
# Comparators
1.4 +21 -9 parrot/string.c
Index: string.c
===================================================================
RCS file: /home/perlcvs/parrot/string.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -w -r1.3 -r1.4
--- string.c 2001/09/10 09:45:50 1.3
+++ string.c 2001/09/13 07:14:24 1.4
@@ -6,8 +6,6 @@
#include "parrot.h"
-static STRING_VTABLE Parrot_string_vtable[enc_max];
-
/* Basic string stuff - creation, enlargement, destruction, etc. */
void
@@ -20,7 +18,7 @@
STRING *s = Sys_Allocate(sizeof(STRING));
s->bufstart = Sys_Allocate(buflen);
Sys_Memcopy(s->bufstart, buffer, buflen);
- s->encoding = encoding;
+ s->encoding = &(Parrot_string_vtable[encoding]);
s->buflen = s->bufused = buflen;
s->flags = flags;
string_compute_strlen(s);
@@ -51,31 +49,45 @@
STRING*
string_copy(STRING *s) {
- return string_make(s->bufstart, s->buflen, s->encoding, s->flags, s->type);
+ return string_make(s->bufstart, s->buflen, s->encoding->which, s->flags,
s->type);
}
/* vtable despatch functions */
-#define ENC_VTABLE(x) Parrot_string_vtable[x->encoding]
+#define ENC_VTABLE(x) x->encoding
IV
string_compute_strlen(STRING* s) {
- return (s->strlen = (ENC_VTABLE(s).compute_strlen)(s));
+ return (s->strlen = (ENC_VTABLE(s)->compute_strlen)(s));
}
IV
string_max_bytes(STRING* s, IV iv) {
- return (ENC_VTABLE(s).max_bytes)(iv);
+ return (ENC_VTABLE(s)->max_bytes)(iv);
}
STRING*
string_concat(STRING* a, STRING* b, IV flags) {
- return (ENC_VTABLE(a).concat)(a, b, flags);
+ return (ENC_VTABLE(a)->concat)(a, b, flags);
+}
+
+STRING*
+string_substr(STRING* src, IV offset, IV length, STRING** d) {
+ STRING *dest;
+ if (offset < 0)
+ offset = src->strlen - offset;
+ if (length < 0)
+ length = 0;
+ if (!d || !*d)
+ dest = string_make(NULL, 0, src->encoding->which, 0, 0);
+ else
+ dest = *d;
+ return (ENC_VTABLE(src)->substr)(src, offset, length, dest);
}
STRING*
string_chopn(STRING* s, IV n) {
if (n > s->strlen)
n = s->strlen;
- return (ENC_VTABLE(s).chopn)(s, n);
+ return (ENC_VTABLE(s)->chopn)(s, n);
}
1.4 +21 -14 parrot/string.h
Index: string.h
===================================================================
RCS file: /home/perlcvs/parrot/string.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -w -r1.3 -r1.4
--- string.h 2001/09/10 09:45:50 1.3
+++ string.h 2001/09/13 07:14:24 1.4
@@ -7,43 +7,47 @@
#if !defined(PARROT_STRING_H_GUARD)
#define PARROT_STRING_H_GUARD 1
-struct parrot_string {
- void *bufstart;
- IV buflen;
- IV bufused;
- IV flags;
- IV strlen;
- IV encoding;
- IV type;
- IV unused;
-};
+typedef struct parrot_string STRING;
+typedef struct string_vtable STRING_VTABLE;
-enum {
+typedef enum {
enc_native,
enc_utf8,
enc_utf16,
enc_utf32,
enc_foreign,
enc_max
-};
+} encoding_t;
-typedef struct parrot_string STRING;
/* String vtable functions */
typedef IV (*string_to_iv_t)(STRING *);
typedef STRING* (*string_iv_to_string_t)(STRING *, IV);
typedef STRING* (*two_strings_iv_to_string_t)(STRING *, STRING *, IV);
+typedef STRING* (*substr_t)(STRING*, IV, IV, STRING*);
typedef IV (*iv_to_iv_t)(IV);
struct string_vtable {
+ encoding_t which; /* What sort of encoding is this? */
string_to_iv_t compute_strlen; /* How long is a piece of string? */
iv_to_iv_t max_bytes; /* I have n characters - how many bytes
should I allocate? */
two_strings_iv_to_string_t concat; /* Append string b to the end of string a */
string_iv_to_string_t chopn; /* Remove n characters from the end of a
string */
+ substr_t substr; /* Substring operation */
};
-typedef struct string_vtable STRING_VTABLE;
+struct parrot_string {
+ void *bufstart;
+ IV buflen;
+ IV bufused;
+ IV flags;
+ IV strlen;
+ STRING_VTABLE* encoding;
+ IV type;
+ IV unused;
+};
+
/* Declarations of accessors */
@@ -51,6 +55,7 @@
IV string_max_bytes(STRING*, IV);
STRING* string_concat(STRING*, STRING*, IV);
STRING* string_chopn(STRING*, IV);
+STRING* string_substr(STRING*, IV, IV, STRING**);
/* Declarations of other functions */
IV string_length(STRING*);
@@ -58,6 +63,8 @@
void string_destroy(STRING* s);
STRING* string_make(void *buffer, IV buflen, IV encoding, IV flags, IV type);
void string_init(void);
+
+STRING_VTABLE Parrot_string_vtable[enc_max];
#include "strnative.h"
#endif
1.4 +24 -7 parrot/strnative.c
Index: strnative.c
===================================================================
RCS file: /home/perlcvs/parrot/strnative.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -w -r1.3 -r1.4
--- strnative.c 2001/09/10 09:45:50 1.3
+++ strnative.c 2001/09/13 07:14:24 1.4
@@ -27,7 +27,7 @@
/* b is now in native format */
string_grow(a, a->strlen + b->strlen);
Sys_Memcopy(a->bufstart + a->strlen, b->bufstart, b->strlen);
- a->strlen = a->buflen = a->bufused = a->strlen + b->strlen;
+ a->strlen = a->bufused = a->strlen + b->strlen;
return a;
}
@@ -38,12 +38,29 @@
return s;
}
+static STRING*
+string_native_substr(STRING* src, IV offset, IV length, STRING* dest)
+{
+ if (dest->encoding->which != enc_native)
+ /* It is now, matey. */
+ dest->encoding = &(Parrot_string_vtable[enc_native]);
+
+ /* Offset and length have already been "normalized" */
+ string_grow(dest, src->strlen - length);
+ Sys_Memcopy(dest->bufstart, src->bufstart + offset, length);
+ dest->strlen = dest->bufused = length;
+
+ return dest;
+}
+
STRING_VTABLE
string_native_vtable (void) {
return (STRING_VTABLE) {
+ enc_native,
string_native_compute_strlen,
string_native_max_bytes,
string_native_concat,
string_native_chopn,
+ string_native_substr,
};
}
1.3 +9 -3 parrot/t/test2.pasm
Index: test2.pasm
===================================================================
RCS file: /home/perlcvs/parrot/t/test2.pasm,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -w -r1.2 -r1.3
--- test2.pasm 2001/09/11 08:26:18 1.2
+++ test2.pasm 2001/09/13 07:14:25 1.3
@@ -1,9 +1,15 @@
set_i_ic I2, 1
set_i_ic I1, 0
set_s_sc S1, "Hello World"
-REDO: eq_i_ic I1, I2, DONE, NEXT
-NEXT: length_i_s I1, S1
+ set_i_ic I3, 0
+ set_i_ic I4, 0
+ length_i_s I5, S1
+WAX: substr_s_s_i S2, S1, I3, I4
+ print_s S2
+ add_i I4, I4, I2
+ eq_i_ic I4, I5, WANE, WAX
+WANE: length_i_s I1, S1
print_s S1
chopn_s_ic S1, 1
- branch_ic REDO
+ eq_i_ic I1, I3, DONE, WANE
DONE: end