diff --git a/delete.c b/delete.c index d4c0b3a..10b9659 100644 --- a/delete.c +++ b/delete.c @@ -26,6 +26,10 @@ static struct deletion { dt_vec, dt_obj, dt_frame, + dt_table, + dt_row, + dt_column, + dt_loop, } type; union { struct { @@ -40,6 +44,24 @@ static struct deletion { struct obj *ref; struct obj *prev; } obj; + struct { + struct table *ref; + struct table *prev; + } table; + struct { + struct row *ref; + struct row *prev; + } row; + struct { + struct var *var; + struct value *values; + struct table *table; + int n; + } col; + struct { + struct loop *ref; + struct loop *prev; + } loop; } u; int group; struct deletion *next; @@ -225,21 +247,85 @@ static void undelete_obj(struct obj *obj, struct obj *prev) } } -/* ----- tables ------------------------------------------------------------ */ + + +/* ----- rows -------------------------------------------------------------- */ void delete_row(struct row *row) { + struct deletion *del; + struct row *walk, *prev; + + groups++; + prev = NULL; + for (walk = row->table->rows; walk != row; walk = walk->next) + prev = walk; + if (prev) + prev->next = row->next; + else + row->table->rows = row->next; + del = new_deletion(dt_row); + del->u.row.ref = row; + del->u.row.prev = prev; } +static void undelete_row(struct row *row, struct row *prev) +{ + if (prev) { + assert(row->next == prev->next); + prev->next = row; + } else { + assert(row->next == row->table->rows); + row->table->rows = row; + } +} + + +/* ----- columns ----------------------------------------------------------- */ + + void delete_column(struct table *table, int n) { + groups++; } +/* ----- tables ------------------------------------------------------------ */ + + void delete_table(struct table *table) { + struct frame *frame = table->vars->frame; + struct deletion *del; + struct table *walk, *prev; + + groups++; + prev = NULL; + for (walk = frame->tables; walk != table; walk = walk->next) + prev = walk; + if (prev) + prev->next = table->next; + else + frame->tables = table->next; + del = new_deletion(dt_table); + del->u.table.ref = table; + del->u.table.prev = prev; +} + + +static void undelete_table(struct table *table, struct table *prev) +{ + struct frame *frame = table->vars->frame; + + if (prev) { + assert(table->next == prev->next); + prev->next = table; + } else { + assert(table->next == frame->tables); + frame->tables = table; + } } @@ -248,6 +334,35 @@ void delete_table(struct table *table) void delete_loop(struct loop *loop) { + struct frame *frame = loop->var.frame; + struct deletion *del; + struct loop *walk, *prev; + + groups++; + prev = NULL; + for (walk = frame->loops; walk != loop; walk = walk->next) + prev = walk; + if (prev) + prev->next = loop->next; + else + frame->loops = loop->next; + del = new_deletion(dt_loop); + del->u.loop.ref = loop; + del->u.loop.prev = prev; +} + + +static void undelete_loop(struct loop *loop, struct loop *prev) +{ + struct frame *frame = loop->var.frame; + + if (prev) { + assert(loop->next == prev->next); + prev->next = loop; + } else { + assert(loop->next == frame->loops); + frame->loops = loop; + } } @@ -347,6 +462,15 @@ static int undelete_one(void) case dt_frame: undelete_frame(del->u.frame.ref, del->u.frame.prev); break; + case dt_loop: + undelete_loop(del->u.loop.ref, del->u.loop.prev); + break; + case dt_table: + undelete_table(del->u.table.ref, del->u.table.prev); + break; + case dt_row: + undelete_row(del->u.row.ref, del->u.row.prev); + break; default: abort(); } diff --git a/expr.c b/expr.c index 6b785d4..3e3d580 100644 --- a/expr.c +++ b/expr.c @@ -101,6 +101,13 @@ int to_unit(struct num *n) /* ----- primary expressions ----------------------------------------------- */ +struct num op_string(const struct expr *self, const struct frame *frame) +{ + fail("cannot evaluate string"); + return undef; +} + + struct num op_num(const struct expr *self, const struct frame *frame) { return self->u.num; diff --git a/expr.h b/expr.h index 82a6fc8..3276dbb 100644 --- a/expr.h +++ b/expr.h @@ -43,6 +43,7 @@ struct expr { union { struct num num; const char *var; + char *str; struct { struct expr *a; struct expr *b; @@ -107,6 +108,7 @@ int to_unit(struct num *n); struct num op_num(const struct expr *self, const struct frame *frame); struct num op_var(const struct expr *self, const struct frame *frame); +struct num op_string(const struct expr *self, const struct frame *frame); struct num op_minus(const struct expr *self, const struct frame *frame); diff --git a/fpd.y b/fpd.y index 1a6094a..9fbe102 100644 --- a/fpd.y +++ b/fpd.y @@ -530,6 +530,11 @@ primary_expr: $$ = new_op(op_var); $$->u.var = $1; } + | STRING + { + $$ = new_op(op_string); + $$->u.str = $1; + } | '(' expr ')' { $$ = $2; diff --git a/gui.c b/gui.c index 64a2d93..8087374 100644 --- a/gui.c +++ b/gui.c @@ -712,7 +712,7 @@ static void build_table(GtkWidget *vbox, struct frame *frame, struct table *table) { GtkWidget *tab, *field; - GtkWidget *evbox; + GtkWidget *evbox, *align; struct var *var; struct row *row; struct value *value; @@ -729,7 +729,9 @@ static void build_table(GtkWidget *vbox, struct frame *frame, return; evbox = gtk_event_box_new(); - gtk_box_pack_start(GTK_BOX(vbox), evbox, FALSE, FALSE, 0); + align = gtk_alignment_new(0, 0, 0, 0); + gtk_container_add(GTK_CONTAINER(align), evbox); + gtk_box_pack_start(GTK_BOX(vbox), align, FALSE, FALSE, 0); tab = gtk_table_new(n_rows+1, n_vars, FALSE); gtk_container_add(GTK_CONTAINER(evbox), tab);