/*
* Copyright (c) 1999 The University of Utah and
* the Computer Systems Laboratory at the University of Utah (CSL).
*
* This file is part of Flick, the Flexible IDL Compiler Kit.
*
* Flick is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Flick is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Flick; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place #330, Boston, MA 02111, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <mom/c/scml.hh>
void scml_token::strip()
{
switch( this->kind ) {
case SCML_TERM_TAG:
switch( this->value.ti->data.kind ) {
case TAG_BOOL:
this->kind = SCML_TERM_BOOL;
this->value.b = this->value.ti->data.tag_data_u.b;
break;
case TAG_INTEGER:
this->kind = SCML_TERM_INT;
this->value.i = this->value.ti->data.tag_data_u.i;
break;
case TAG_FLOAT:
this->kind = SCML_TERM_FLOAT;
this->value.f = this->value.ti->data.tag_data_u.f;
break;
case TAG_CAST_SCOPED_NAME:
case TAG_CAST_DEF:
case TAG_CAST_TYPE:
case TAG_CAST_EXPR:
case TAG_CAST_STMT:
case TAG_CAST_INIT:
case TAG_STRING: {
struct scml_string *ss;
this->kind = SCML_TERM_STRING;
ss = new scml_string;
*ss->add_component() = this->value.ti->data;
this->value.str = ss;
break;
}
case TAG_TAG_LIST:
this->kind = SCML_TERM_TAG_LIST;
this->value.tl = this->value.ti->data.tag_data_u.tl;
break;
case TAG_REF: {
struct scml_string *ss;
if( (ss = scml_string::ptr(this->value.ti->
data.tag_data_u.ref)) ) {
this->kind = SCML_TERM_STRING;
this->value.str = ss;
}
break;
}
default:
break;
}
break;
default:
break;
}
}
void scml_token::promote(int required_kind)
{
switch( required_kind ) {
case SCML_TERM_INT:
switch( this->kind ) {
case SCML_TERM_INT:
break;
default:
this->kind = SCML_ERROR;
break;
}
break;
case SCML_TERM_FLOAT:
switch( this->kind ) {
case SCML_TERM_FLOAT:
break;
case SCML_TERM_INT:
this->kind = SCML_TERM_FLOAT;
this->value.f = this->value.i;
break;
default:
this->kind = SCML_ERROR;
break;
}
break;
case SCML_TERM_TAG: {
tag_data td;
switch( this->kind ) {
case SCML_TERM_BOOL:
this->kind = SCML_TERM_BOOL;
td = create_tag_data(TAG_BOOL, 1);
td.tag_data_u.b = this->value.i;
break;
case SCML_TERM_STRING:
this->kind = SCML_TERM_TAG;
td = create_tag_data(TAG_REF, 1);
td.tag_data_u.ref = this->value.str->tag_ref();
this->value.ti = create_tag_item("", &td);
break;
case SCML_TERM_INT:
this->kind = SCML_TERM_TAG;
td = create_tag_data(TAG_INTEGER, 1);
td.tag_data_u.i = this->value.i;
this->value.ti = create_tag_item("", &td);
break;
case SCML_TERM_FLOAT:
this->kind = SCML_TERM_TAG;
td = create_tag_data(TAG_FLOAT, 1);
td.tag_data_u.f = this->value.f;
this->value.ti = create_tag_item("", &td);
break;
case SCML_TERM_TAG:
break;
default:
this->kind = SCML_ERROR;
break;
}
break;
}
case SCML_TERM_STRING: {
struct scml_string *ss;
tag_data *td;
this->strip();
switch( this->kind ) {
case SCML_TERM_BOOL:
this->kind = SCML_TERM_STRING;
ss = new scml_string;
td = ss->add_component();
td->kind = TAG_STRING;
td->tag_data_u.str = flick_asprintf("%s",
this->value.i ?
"true" : "false");
this->value.str = ss;
break;
case SCML_TERM_INT:
this->kind = SCML_TERM_STRING;
ss = new scml_string;
td = ss->add_component();
td->kind = TAG_STRING;
td->tag_data_u.str = flick_asprintf("%d",
this->value.i);
this->value.str = ss;
break;
case SCML_TERM_FLOAT:
this->kind = SCML_TERM_STRING;
ss = new scml_string;
td = ss->add_component();
td->kind = TAG_STRING;
td->tag_data_u.str = flick_asprintf("%f",
this->value.f);
this->value.str = ss;
break;
case SCML_TERM_STRING:
break;
default:
this->kind = SCML_ERROR;
break;
}
break;
}
case SCML_TERM_TAG_LIST:
switch( this->kind ) {
case SCML_TERM_TAG_LIST:
break;
default:
this->kind = SCML_ERROR;
break;
}
break;
default:
this->kind = SCML_ERROR;
break;
}
}
const char *scml_kind_map[SCML_NT_MAX + 1] = {
"SCML_NONE",
"SCML_IGNORE",
"SCML_ERROR",
"SCML_DONE",
"SCML_COL_POS",
"SCML_ROW_POS",
"SCML_TERM",
"SCML_TERM_BOOL",
"SCML_TERM_INT",
"SCML_TERM_FLOAT",
"SCML_TERM_STRING",
"SCML_TERM_TAG",
"SCML_TERM_TAG_LIST",
"SCML_TERM_TEXT",
"SCML_TERM_ESCAPE",
"SCML_TERM_ID",
"SCML_TERM_VERBATIM",
"SCML_TERM_LPAREN",
"SCML_TERM_RPAREN",
"SCML_TERM_LBRACE",
"SCML_TERM_RBRACE",
"SCML_TERM_LCURLY",
"SCML_TERM_RCURLY",
"SCML_TERM_SLASH",
"SCML_TERM_LT",
"SCML_TERM_GT",
"SCML_TERM_MAX",
"SCML_NT",
"SCML_NT_COMMAND",
"SCML_NT_SET",
"SCML_NT_ASSIGN",
"SCML_NT_PLUS",
"SCML_NT_MINUS",
"SCML_NT_DIV",
"SCML_NT_MOD",
"SCML_NT_MULT",
"SCML_NT_COND",
"SCML_NT_COLON",
"SCML_NT_COMMA",
"SCML_NT_EQUAL",
"SCML_NT_NOT_EQUAL",
"SCML_NT_LT",
"SCML_NT_GT",
"SCML_NT_LE",
"SCML_NT_GE",
"SCML_NT_AND",
"SCML_NT_LAND",
"SCML_NT_OR",
"SCML_NT_LOR",
"SCML_NT_XOR",
"SCML_NT_NOT",
"SCML_NT_DOT",
"SCML_NT_SCOPE_RES",
"SCML_NT_NAME",
"SCML_NT_EXPR",
"SCML_NT_TAG",
"SCML_NT_SEL",
"SCML_NT_INIT",
"SCML_NT_MAX"
};
void scml_token::print()
{
printf(":%s", scml_kind_map[this->kind]);
switch( this->kind ) {
case SCML_NONE:
case SCML_DONE:
break;
case SCML_IGNORE:
printf("=ignore");
break;
case SCML_ERROR:
printf("=error");
break;
case SCML_COL_POS:
printf("=%d", this->value.i);
break;
case SCML_ROW_POS:
printf("=%d", this->value.i);
break;
case SCML_TERM_BOOL:
printf("=%s", this->value.b ? "true" : "false");
break;
case SCML_TERM_INT:
printf("=%d", this->value.i);
break;
case SCML_TERM_FLOAT:
printf("=%f", this->value.f);
break;
case SCML_TERM_STRING:
printf("=\"");
this->value.str->print(0);
printf("\"");
break;
case SCML_TERM_TEXT:
printf("=\'%s\'", this->value.text);
break;
case SCML_TERM_ESCAPE:
printf("=%s", this->value.escape);
break;
case SCML_TERM_ID:
printf("=%s", this->value.id);
break;
case SCML_TERM_VERBATIM:
printf("=%s", this->value.text);
break;
case SCML_TERM_TAG:
print_tag(0, this->value.ti);
break;
case SCML_TERM_TAG_LIST: {
tag_item ti;
ti.tag = ir_strlit("");
ti.data.kind = TAG_TAG_LIST;
ti.data.tag_data_u.tl = this->value.tl;
printf("={\n");
print_tag(0, &ti);
printf("}\n");
break;
}
case SCML_NT_COMMAND:
if( this->value.children ) {
int lpc;
printf("=<");
for( lpc = 0;
this->value.children[lpc].kind != SCML_NONE;
lpc++ ) {
if( lpc > 0 )
printf(" ");
this->value.children[lpc].print();
}
printf(">");
}
break;
case SCML_NT_SET:
if( this->value.children ) {
this->value.children[0].print();
printf(" = ");
this->value.children[1].print();
}
break;
case SCML_NT_PLUS:
if( this->value.children ) {
printf("(");
this->value.children[0].print();
printf(" + ");
this->value.children[1].print();
printf(")");
}
break;
case SCML_NT_MINUS:
if( this->value.children ) {
printf("(");
this->value.children[0].print();
printf(" - ");
this->value.children[1].print();
printf(")");
}
break;
case SCML_NT_DIV:
if( this->value.children ) {
this->value.children[0].print();
printf(" / ");
this->value.children[1].print();
}
break;
case SCML_NT_MOD:
if( this->value.children ) {
this->value.children[0].print();
printf(" %% ");
this->value.children[1].print();
}
break;
case SCML_NT_MULT:
if( this->value.children ) {
printf("(");
this->value.children[0].print();
printf(" * ");
this->value.children[1].print();
printf(")");
}
break;
case SCML_NT_COLON:
if( this->value.children ) {
this->value.children[0].print();
printf(" : ");
this->value.children[1].print();
}
break;
case SCML_NT_EQUAL:
if( this->value.children ) {
this->value.children[0].print();
printf(" == ");
this->value.children[1].print();
}
break;
case SCML_NT_NOT_EQUAL:
if( this->value.children ) {
this->value.children[0].print();
printf(" != ");
this->value.children[1].print();
}
break;
case SCML_NT_LT:
if( this->value.children ) {
this->value.children[0].print();
printf(" < ");
this->value.children[1].print();
}
break;
case SCML_NT_GT:
if( this->value.children ) {
this->value.children[0].print();
printf(" > ");
this->value.children[1].print();
}
break;
case SCML_NT_LE:
if( this->value.children ) {
this->value.children[0].print();
printf(" <= ");
this->value.children[1].print();
}
break;
case SCML_NT_GE:
if( this->value.children ) {
this->value.children[0].print();
printf(" >= ");
this->value.children[1].print();
}
break;
case SCML_NT_AND:
if( this->value.children ) {
this->value.children[0].print();
printf(" & ");
this->value.children[1].print();
}
break;
case SCML_NT_LAND:
if( this->value.children ) {
this->value.children[0].print();
printf(" && ");
this->value.children[1].print();
}
break;
case SCML_NT_OR:
if( this->value.children ) {
this->value.children[0].print();
printf(" | ");
this->value.children[1].print();
}
break;
case SCML_NT_LOR:
if( this->value.children ) {
this->value.children[0].print();
printf(" || ");
this->value.children[1].print();
}
break;
case SCML_NT_NOT:
if( this->value.children ) {
printf("! ");
this->value.children[0].print();
}
break;
case SCML_NT_DOT:
if( this->value.children ) {
this->value.children[0].print();
printf(" . ");
this->value.children[1].print();
}
break;
case SCML_NT_SCOPE_RES:
if( this->value.children ) {
this->value.children[0].print();
printf(" :: ");
this->value.children[1].print();
}
break;
case SCML_NT_EXPR:
if( this->value.children ) {
this->value.children[0].print();
}
break;
case SCML_NT_TAG:
if( this->value.children ) {
this->value.children[0].print();
printf(" : ");
this->value.children[1].print();
}
break;
case SCML_NT_NAME:
this->value.children[0].print();
break;
case SCML_NT_SEL:
if( this->value.children ) {
this->value.children[0].print();
printf(" [ ");
this->value.children[1].print();
printf(" ] ");
}
break;
case SCML_NT_INIT:
if( this->value.children ) {
int lpc;
printf(" { ");
for( lpc = 0;
this->value.children[lpc].kind != SCML_NONE;
lpc++ ) {
if( lpc > 0 )
printf(" ");
this->value.children[lpc].print();
}
printf( " } ");
}
break;
default:
printf("=<>");
break;
}
}
int scml_token::is_expr()
{
int retval = 0;
switch( this->kind ) {
case SCML_TERM_INT:
case SCML_TERM_BOOL:
case SCML_TERM_FLOAT:
case SCML_TERM_STRING:
case SCML_TERM_ID:
case SCML_NT_EXPR:
case SCML_NT_NAME:
case SCML_NT_TAG:
case SCML_NT_SEL:
case SCML_NT_INIT:
retval = this->kind;
break;
default:
break;
}
return( retval );
}
int scml_token::is_value()
{
int retval = 0;
switch( this->kind ) {
case SCML_TERM_INT:
case SCML_TERM_BOOL:
case SCML_TERM_FLOAT:
case SCML_TERM_STRING:
case SCML_TERM_TAG:
case SCML_TERM_TAG_LIST:
case SCML_TERM_TEXT:
case SCML_TERM_ESCAPE:
case SCML_TERM_ID:
case SCML_TERM_VERBATIM:
case SCML_NT_COMMAND:
case SCML_NT_EXPR:
case SCML_NT_TAG:
case SCML_NT_SEL:
case SCML_NT_NAME:
case SCML_NT_INIT:
retval = this->kind;
break;
default:
break;
}
return( retval );
}
int scml_token::is_operator()
{
int retval = 0;
switch( this->kind ) {
case SCML_NT_ASSIGN:
case SCML_NT_PLUS:
case SCML_NT_MINUS:
case SCML_NT_DIV:
case SCML_NT_MOD:
case SCML_NT_MULT:
case SCML_NT_COLON:
case SCML_NT_EQUAL:
case SCML_NT_NOT_EQUAL:
case SCML_NT_LT:
case SCML_NT_GT:
case SCML_NT_LE:
case SCML_NT_GE:
case SCML_NT_AND:
case SCML_NT_LAND:
case SCML_NT_OR:
case SCML_NT_LOR:
case SCML_NT_NOT:
case SCML_NT_DOT:
case SCML_NT_SCOPE_RES:
retval = this->kind;
break;
default:
break;
}
return( retval );
}
int scml_token::is_container()
{
int retval = 0;
switch( this->kind ) {
case SCML_TERM_LPAREN:
case SCML_TERM_RPAREN:
retval = SCML_NT_EXPR;
break;
case SCML_TERM_LBRACE:
case SCML_TERM_RBRACE:
retval = SCML_NT_SEL;
break;
case SCML_TERM_LCURLY:
case SCML_TERM_RCURLY:
retval = SCML_NT_INIT;
break;
case SCML_TERM_LT:
case SCML_TERM_GT:
retval = SCML_NT_COMMAND;
break;
default:
break;
}
return( retval );
}
struct scml_prec {
int op;
int prec;
};
struct scml_prec scml_op_prec[] = {
{SCML_NT_ASSIGN, 0},
{SCML_NT_COLON, 1},
{SCML_NT_SCOPE_RES, 1},
{SCML_NT_LOR, 2},
{SCML_NT_LAND, 3},
{SCML_NT_OR, 4},
{SCML_NT_AND, 5},
{SCML_NT_EQUAL, 6},
{SCML_NT_NOT_EQUAL, 6},
{SCML_NT_LT, 7},
{SCML_NT_GT, 7},
{SCML_NT_LE, 7},
{SCML_NT_GE, 7},
{SCML_NT_PLUS, 8},
{SCML_NT_MINUS, 8},
{SCML_NT_MULT, 9},
{SCML_NT_DIV, 9},
{SCML_NT_MOD, 9},
{SCML_TERM_LBRACE, 10},
{SCML_TERM_RBRACE, 10},
{SCML_NT_NOT, 12},
{SCML_NT_COMMA, 12},
{SCML_NT_DOT, 13},
{SCML_TERM_LPAREN, 13},
{SCML_TERM_RPAREN, 13},
{SCML_TERM_LCURLY, 13},
{SCML_TERM_RCURLY, 13},
{SCML_NONE, 0}
};
int scml_token::get_prec()
{
int retval = -1;
int lpc;
for( lpc = 0; (scml_op_prec[lpc].op != SCML_NONE) && (retval == -1);
lpc++ ) {
if( this->kind == scml_op_prec[lpc].op )
retval = scml_op_prec[lpc].prec;
}
return( retval );
}
char *scml_token::get_identifier()
{
char *retval = 0;
switch( this->kind ) {
case SCML_TERM_ID:
retval = flick_asprintf("%s", this->value.id);
break;
case SCML_TERM_ESCAPE:
retval = flick_asprintf("%s", this->value.escape);
break;
case SCML_NT_NAME:
retval = this->value.children[0].get_identifier();
break;
case SCML_NT_SCOPE_RES: {
char *left, *right;
left = this->value.children[0].get_identifier();
right = this->value.children[1].get_identifier();
retval = flick_asprintf("%s::%s", left, right);
free(left);
free(right);
break;
}
default:
break;
}
return( retval );
}
scml_token_sequence::scml_token_sequence()
{
this->stream_pos = 0;
this->indent = 0;
this->val = 0;
this->len = 0;
}
scml_token_sequence::~scml_token_sequence()
{
}
char *scml_token_sequence::tag_ref()
{
return( ptr_to_tag_ref("struct scml_token_sequence *", this) );
}
struct scml_token_sequence *scml_token_sequence::ptr(char *ref)
{
return( (struct scml_token_sequence *)
tag_ref_to_ptr("struct scml_token_sequence *", ref) );
}
void scml_token_sequence::print()
{
int lpc;
printf("sequence=\"");
for( lpc = 0; lpc < this->len; lpc++ ) {
this->val[lpc].print();
}
printf("\"");
}
void scml_token_sequence::set_value(struct scml_token *st)
{
this->val = st;
}
struct scml_token *scml_token_sequence::get_value()
{
return( this->val );
}
void scml_token_sequence::set_length(int the_len)
{
this->len = the_len;
}
int scml_token_sequence::get_length()
{
return( this->len );
}
void scml_token_sequence::set_stream_pos(struct scml_stream_pos *ssp)
{
this->stream_pos = ssp;
}
struct scml_stream_pos *scml_token_sequence::get_stream_pos()
{
return( this->stream_pos );
}
void scml_token_sequence::set_indent(int offset)
{
this->indent = offset;
}
int scml_token_sequence::get_indent()
{
return( this->indent );
}
int scml_token_stack::default_max = 10;
int scml_token_stack::default_inc = 10;
scml_token_stack::scml_token_stack()
{
this->val = (struct scml_token *)mustmalloc(default_max *
sizeof(struct scml_token));
this->top = -1;
this->max = default_max;
}
scml_token_stack::~scml_token_stack()
{
free( this->val );
}
void scml_token_stack::push(struct scml_token &st)
{
this->top++;
if( this->top >= this->max ) {
this->max += default_inc;
this->val = (struct scml_token *)
mustrealloc(this->val,
this->max * sizeof(struct scml_token));
}
this->val[this->top] = st;
}
void scml_token_stack::pop()
{
this->top--;
}
struct scml_token *scml_token_stack::index(int offset)
{
if( offset > 0 )
panic("Less than zero offset used in index");
else if( (this->top + offset) < 0 )
panic("Too large an offset used in index");
return( &(this->val[this->top + offset]) );
}
int scml_token_stack::count()
{
return( this->top + 1 );
}
void scml_token_stack::print()
{
int lpc;
for( lpc = this->top; lpc >= 0; lpc-- ) {
this->val[lpc].print();
printf("\n");
}
}
syntax highlighted by Code2HTML, v. 0.9.1