diff options
Diffstat (limited to 'support/ltx2x/l2xistd.c')
-rw-r--r-- | support/ltx2x/l2xistd.c | 667 |
1 files changed, 667 insertions, 0 deletions
diff --git a/support/ltx2x/l2xistd.c b/support/ltx2x/l2xistd.c new file mode 100644 index 0000000000..49c3dbc9cb --- /dev/null +++ b/support/ltx2x/l2xistd.c @@ -0,0 +1,667 @@ +/* l2xistd.c LTX2X interpreter Parsing for calls to standard functions */ +/* Written by: Peter Wilson, CUA pwilson@cme.nist.gov */ +/* This code is partly based on algorithms presented by Ronald Mak in */ +/* "Writing Compilers & Interpreters", John Wiley & Sons, 1991 */ + +#include <stdio.h> +#include "l2xicmon.h" +#include "l2xierr.h" +#include "l2xiscan.h" +#include "l2xisymt.h" +#include "l2xiprse.h" +#include "l2xiidbg.h" + + +#define DEFAULT_NUMERIC_FIELD_WIDTH 10 +#define DEFAULT_PRECISION 2 + +/* EXTERNALS */ + +extern TOKEN_CODE token; +extern char word_string[]; +extern SYMTAB_NODE_PTR symtab_display[]; +extern int level; +extern TOKEN_CODE follow_parm_list[]; +extern TOKEN_CODE statement_end_list[]; + +/* FORWARDS */ + +TYPE_STRUCT_PTR eof_eoln(), abs_sqr(), arctan_cos_exp_ln_sin_sqrt(), + pred_succ(), odd(), ord(), round_trunc(); +TYPE_STRUCT_PTR atan(), exists_etc(), nvl_etc(); +TYPE_STRUCT_PTR rexpr_etc(), hibound_etc(), length_etc(); + +/***************************************************************************/ +/* standard_routine_call (rtn_idp) Process call to standard function */ +/* return pointer to type structure of the call */ + +TYPE_STRUCT_PTR standard_routine_call(rtn_idp) +SYMTAB_NODE_PTR rtn_idp; /* routine id */ +{ + + switch (rtn_idp->defn.info.routine.key) { + case READ: + case READLN: { + read_readln(rtn_idp); + return(NULL); + } + case WRITE: + case WRITELN: { + write_writeln(rtn_idp); + return(NULL); + } + case EOFF: + case EOLN: { + return(eof_eoln(rtn_idp)); + } + case ABS: /* real or int arg -> real or int */ + { + return(abs_sqr()); + } + case COS: /* real or int arg -> real */ + case EXP: + case SIN: + case SQRT: + case XACOS: + case XASIN: + case XLOG: + case XLOG2: + case XLOG10: + case XTAN: { + return(arctan_cos_exp_ln_sin_sqrt()); + } + case XATAN: { + return(atan()); + } + case ODD: { /* int arg -> boolean */ + return(odd()); + } + case ROUND: /* real arg -> int */ + case TRUNC: { + return(round_trunc()); + } + case L2XPRINT: + case L2XPRINTLN: { /* extra for ltx2x */ + print_println(rtn_idp); + return(NULL); + } + case L2XSYSTEM: { /* extra for ltx2x */ + system_etc(rtn_idp); + return(NULL); + } + case L2XREXPR: { /* extra for ltx2x two strings -> boolean */ + return(rexpr_etc()); + } + case XEXISTS: { /* any arg -> boolean */ + return(exists_etc()); + } + case XNVL: { /* two args -> one of these */ + return(nvl_etc()); + } + case XHIBOUND: /* agg arg -> int */ + case XHIINDEX: + case XLOBOUND: + case XLOINDEX: + case XSIZEOF: { + return(hibound_etc()); + } + case XLENGTH: { /* string arg -> int */ + return(length_etc()); + } + case XINSERT: + case XREMOVE: { + insert_etc(rtn_idp); + return(NULL); + } + case XBLENGTH: /* unimplemented EXPRESS functions */ + case XFORMAT: + case XROLESOF: + case XTYPEOF: + case XUSEDIN: + case XVALUE: + case XVALUE_IN: + case XVALUE_UNIQUE: { + error(UNIMPLEMENTED_FEATURE); + return(NULL); + } + default : { /* should not be here */ + error(UNEXPECTED_TOKEN); + return(NULL); + } + } /* end switch */ +} /* end standard_routine_call */ +/***************************************************************************/ + + +/***************************************************************************/ +/* read_readln(rtn_idp) Process call to read or readln */ + +read_readln(rtn_idp) +SYMTAB_NODE_PTR rtn_idp; +{ + TYPE_STRUCT_PTR actual_parm_tp; /* actual param type */ + + /* parameters are optional for readln */ + if (token == LPAREN) { + do { + get_token(); + /* actuals should be variables, but parse anyway */ + if (token == IDENTIFIER) { + SYMTAB_NODE_PTR idp; + search_and_find_all_symtab(idp); + actual_parm_tp = base_type(variable(idp, VARPARM_USE)); +/* if (actual_parm_tp->form != SCALAR_FORM) error(INCOMPATIBLE_TYPES); */ + if (actual_parm_tp != integer_typep && + actual_parm_tp != real_typep && + actual_parm_tp != logical_typep && + actual_parm_tp != string_typep) { + error(INCOMPATIBLE_TYPES); + } + } + else { + actual_parm_tp = expression(); + error(INVALID_VAR_PARM); + } + /* sync. Should be , or ) */ + synchronize(follow_parm_list, statement_end_list, NULL); + } while (token == COMMA); /* end do */ + if_token_get_else_error(RPAREN, MISSING_RPAREN); + } /* end if */ + else { + if (rtn_idp->defn.info.routine.key == READ) error(WRONG_NUMBER_OF_PARMS); + } + +} /* end read_readln */ +/***************************************************************************/ + + + +/***************************************************************************/ +/* write_writeln(rtn_idp) Process call to write or writeln */ +/* Each actual parameter can be: */ +/* <expr> or */ +/* <expr> : <expr> or */ +/* <expr> : <expr> : <expr> */ + +write_writeln(rtn_idp) +SYMTAB_NODE_PTR rtn_idp; +{ + TYPE_STRUCT_PTR actual_parm_tp; /* actual parm type */ + TYPE_STRUCT_PTR field_width_tp, precision_tp; + + /* params are optional for writeln */ + if (token == LPAREN) { + do { + get_token(); + actual_parm_tp = base_type(expression()); + + if ((actual_parm_tp->form != SCALAR_FORM) && + (actual_parm_tp != logical_typep) && + (actual_parm_tp->form != STRING_FORM) && + (actual_parm_tp->form != ENUM_FORM)) + error(INVALID_EXPRESSION); + + /* optional field width expression */ + if (token == COLON) { + get_token(); + field_width_tp = base_type(expression()); + if (field_width_tp != integer_typep) error(INCOMPATIBLE_TYPES); + + /* optional precision spec */ + if (token == COLON) { + get_token(); + precision_tp = base_type(expression()); + if (precision_tp != integer_typep) error(INCOMPATIBLE_TYPES); + + } /* end colon if */ + } /* end colon if */ + /* sync. Should be , or ) */ + synchronize(follow_parm_list, statement_end_list, NULL); + } while (token == COMMA); /* end do */ + if_token_get_else_error(RPAREN, MISSING_RPAREN); + } /* end if */ + else { + if (rtn_idp->defn.info.routine.key == WRITE) error(WRONG_NUMBER_OF_PARMS); + } + +} /* end write_writeln */ +/***************************************************************************/ + + + +/***************************************************************************/ +/* print_println(rtn_idp) Process call to print or println */ +/* Each actual parameter can be: */ +/* <expr> or */ +/* <expr> : <expr> or */ +/* <expr> : <expr> : <expr> */ +/* At this point, identical to write_writeln */ + +print_println(rtn_idp) +SYMTAB_NODE_PTR rtn_idp; +{ + TYPE_STRUCT_PTR actual_parm_tp; /* actual parm type */ + TYPE_STRUCT_PTR field_width_tp, precision_tp; + + /* params are optional for println */ + if (token == LPAREN) { + do { + get_token(); + actual_parm_tp = base_type(expression()); + + if ((actual_parm_tp->form != SCALAR_FORM) && + (actual_parm_tp != logical_typep) && + (actual_parm_tp->form != STRING_FORM) && + (actual_parm_tp->form != ENUM_FORM)) + error(INVALID_EXPRESSION); + + /* optional field width expression */ + if (token == COLON) { + get_token(); + field_width_tp = base_type(expression()); + if (field_width_tp != integer_typep) error(INCOMPATIBLE_TYPES); + + /* optional precision spec */ + if (token == COLON) { + get_token(); + precision_tp = base_type(expression()); + if (precision_tp != integer_typep) error(INCOMPATIBLE_TYPES); + + } /* end colon if */ + } /* end colon if */ + /* sync. Should be , or ) */ + synchronize(follow_parm_list, statement_end_list, NULL); + } while (token == COMMA); /* end do */ + if_token_get_else_error(RPAREN, MISSING_RPAREN); + } /* end if */ + else { + if (rtn_idp->defn.info.routine.key == WRITE) error(WRONG_NUMBER_OF_PARMS); + } + +} /* end print_println */ +/***************************************************************************/ + + + +/***************************************************************************/ +/* eof_eoln(rtn_idp) Process call to eof or eoln. No parameters. */ +/* return boolean result. */ + +TYPE_STRUCT_PTR eof_eoln(rtn_idp) +SYMTAB_NODE_PTR rtn_idp; +{ + TYPE_STRUCT_PTR result_tp = logical_typep; + + if (token == LPAREN) { + error(WRONG_NUMBER_OF_PARMS); + actual_parm_list(rtn_idp, FALSE); + } + return(result_tp); +} /* end eof_eoln */ +/***************************************************************************/ + + + +/***************************************************************************/ +/* system_etc() Process call to system, etc */ +/* fun('string') */ +/* One string parameter, no return value */ +/* at entry, token is `fun' */ +/* at exit, token is after closing ) */ + +system_etc(rtn_idp) +SYMTAB_NODE_PTR rtn_idp; /* routine id */ +{ + TYPE_STRUCT_PTR actual_parm_tp; /* actual parm type */ + + if (token == LPAREN) { + get_token(); + actual_parm_tp = base_type(expression()); + if (actual_parm_tp != string_typep && + (actual_parm_tp->form != STRING_FORM)) { + error(INVALID_EXPRESSION); + } + if_token_get_else_error(RPAREN, MISSING_RPAREN); + } + else { + error(WRONG_NUMBER_OF_PARMS); + } + + return; +} /* end SYSTEM_ETC */ +/***************************************************************************/ + + + +/***************************************************************************/ +/* length_etc() Process call to length, etc */ +/* fun('string') */ +/* One string parameter, integer return value */ +/* at entry, token is `fun' */ +/* at exit, token is after closing ) */ + +TYPE_STRUCT_PTR length_etc() +{ + TYPE_STRUCT_PTR actual_parm_tp; /* actual parm type */ + TYPE_STRUCT_PTR result_tp = integer_typep; /* result type */ + if (token == LPAREN) { + get_token(); + actual_parm_tp = base_type(expression()); + if (actual_parm_tp != string_typep && + (actual_parm_tp->form != STRING_FORM)) { + error(INVALID_EXPRESSION); + } + if_token_get_else_error(RPAREN, MISSING_RPAREN); + } + else { + error(WRONG_NUMBER_OF_PARMS); + } + + return(result_tp); +} /* end LENGTH_ETC */ +/***************************************************************************/ + + + +/***************************************************************************/ +/* hibound_etc() Process call to hibound, etc */ +/* fun(agg) */ +/* One aggregate parameter, integer return value */ +/* at entry, token is `fun' */ +/* at exit, token is after closing ) */ + +TYPE_STRUCT_PTR hibound_etc() +{ + TYPE_STRUCT_PTR actual_parm_tp; /* actual parm type */ + TYPE_STRUCT_PTR result_tp = integer_typep; /* result type */ + if (token == LPAREN) { + get_token(); + actual_parm_tp = base_type(expression()); + if ((actual_parm_tp->form != ARRAY_FORM) && + (actual_parm_tp->form != BAG_FORM) && + (actual_parm_tp->form != LIST_FORM) && + (actual_parm_tp->form != SET_FORM) ) { + error(INVALID_EXPRESSION); + } + if_token_get_else_error(RPAREN, MISSING_RPAREN); + } + else { + error(WRONG_NUMBER_OF_PARMS); + } + + return(result_tp); +} /* end HIBOUND_ETC */ +/***************************************************************************/ + + + +/***************************************************************************/ +/* rexpr_etc() Process call to rexpr, etc */ +/* fun('string', 'string') */ +/* Two string parameters, boolean return value */ +/* at entry, token is `fun' */ +/* at exit, token is after closing ) */ + +TYPE_STRUCT_PTR rexpr_etc() +{ + TYPE_STRUCT_PTR actual_parm_tp; /* actual parm type */ + TYPE_STRUCT_PTR result_tp = logical_typep; /* result type */ + + if (token == LPAREN) { + get_token(); + actual_parm_tp = base_type(expression()); + if (actual_parm_tp != string_typep && + actual_parm_tp->form != STRING_FORM) { + error(INVALID_EXPRESSION); + } + if_token_get_else_error(COMMA, MISSING_COMMA); + actual_parm_tp = base_type(expression()); + if (actual_parm_tp != string_typep && + actual_parm_tp->form != STRING_FORM) { + error(INVALID_EXPRESSION); + } + if_token_get_else_error(RPAREN, MISSING_RPAREN); + } + else { + error(WRONG_NUMBER_OF_PARMS); + } + + return(result_tp); +} /* end REXPR_ETC */ +/***************************************************************************/ + + + +/***************************************************************************/ +/* exists_etc Process call to exists, etc */ +/* fun(any) -> boolean */ +/* any type parm -> boolean result */ + +TYPE_STRUCT_PTR exists_etc() +{ + TYPE_STRUCT_PTR parm_tp; /* actual param type */ + TYPE_STRUCT_PTR result_tp = logical_typep; /* result type */ + + if (token == LPAREN) { + get_token(); + if_token_get_else_error(RPAREN, MISSING_RPAREN); + } + else error(WRONG_NUMBER_OF_PARMS); + + return(result_tp); +} /* end EXISTS_ETC */ +/***************************************************************************/ + + + +/***************************************************************************/ +/* nvl_etc Process NVL, etc */ +/* fun(p1, p2) -> p1 or p2 */ +/* Two args, any type, returns one of them */ + +TYPE_STRUCT_PTR nvl_etc() +{ + TYPE_STRUCT_PTR parm_tp; /* actual param type */ + + if (token == LPAREN) { + get_token(); + parm_tp = base_type(expression()); + + if_token_get_else_error(COMMA, MISSING_COMMA); + /* PERHAPS SHOULD CHECK FOR ASSIGNMENT COMPATIBILITY */ +/* +* if (parm_tp != base_type(expression()) ) { +* error(INCOMPATIBLE_TYPES); +* } +*/ + if_token_get_else_error(RPAREN, MISSING_RPAREN); + } + else error(WRONG_NUMBER_OF_PARMS); + + return(parm_tp); +} /* end NVL_ETC */ +/***************************************************************************/ + + + +/***************************************************************************/ +/* abs_sqr Process call to abs or sqr. */ +/* integer parm -> integer result */ +/* real parm -> real result */ + +TYPE_STRUCT_PTR abs_sqr() +{ + TYPE_STRUCT_PTR parm_tp; /* actual param type */ + TYPE_STRUCT_PTR result_tp; /* result type */ + + if (token == LPAREN) { + get_token(); + parm_tp = base_type(expression()); + + if ((parm_tp != integer_typep) && (parm_tp != real_typep)) { + error(INCOMPATIBLE_TYPES); + result_tp = real_typep; + } + else result_tp = parm_tp; + + if_token_get_else_error(RPAREN, MISSING_RPAREN); + } + else error(WRONG_NUMBER_OF_PARMS); + + return(result_tp); +} /* end abs_sqr */ +/***************************************************************************/ + + + +/***************************************************************************/ +/* arctan_cos_exp_ln_sin_sqrt Process call to these */ +/* integer parm -> real result */ +/* real parm -> real result */ + +TYPE_STRUCT_PTR arctan_cos_exp_ln_sin_sqrt() +{ + TYPE_STRUCT_PTR parm_tp; /* actual param type */ + + if (token == LPAREN) { + get_token(); + parm_tp = base_type(expression()); + + if ((parm_tp != integer_typep) && (parm_tp != real_typep)) { + error(INCOMPATIBLE_TYPES); + } + if_token_get_else_error(RPAREN, MISSING_RPAREN); + } + else error(WRONG_NUMBER_OF_PARMS); + + return(real_typep); +} /* end arctan_cos_exp_ln_sin_sqrt */ +/***************************************************************************/ + + + +/***************************************************************************/ +/* atan Process call to these */ +/* fun(p1, p2) */ +/* integer parm -> real result */ +/* real parm -> real result */ + +TYPE_STRUCT_PTR atan() +{ + TYPE_STRUCT_PTR parm_tp; /* actual param type */ + + if (token == LPAREN) { + get_token(); + parm_tp = base_type(expression()); + + if ((parm_tp != integer_typep) && (parm_tp != real_typep)) { + error(INCOMPATIBLE_TYPES); + } + if_token_get_else_error(COMMA, MISSING_COMMA); + parm_tp = base_type(expression()); + if ((parm_tp != integer_typep) && (parm_tp != real_typep)) { + error(INCOMPATIBLE_TYPES); + } + if_token_get_else_error(RPAREN, MISSING_RPAREN); + } + else error(WRONG_NUMBER_OF_PARMS); + + return(real_typep); +} /* end ATAN */ +/***************************************************************************/ + + + + + +/***************************************************************************/ +/* odd Process call to odd. */ +/* integer parm -> boolean result */ + +TYPE_STRUCT_PTR odd() +{ + TYPE_STRUCT_PTR parm_tp; /* actual param type */ + TYPE_STRUCT_PTR result_tp = logical_typep; + + if (token == LPAREN) { + get_token(); + parm_tp = base_type(expression()); + + if (parm_tp != integer_typep) { + error(INCOMPATIBLE_TYPES); + } + + if_token_get_else_error(RPAREN, MISSING_RPAREN); + } + else error(WRONG_NUMBER_OF_PARMS); + + return(logical_typep); +} /* end odd */ +/***************************************************************************/ + + + +/***************************************************************************/ +/* round_trunc Process call to round or trunc. */ +/* real parm -> integer result */ + +TYPE_STRUCT_PTR round_trunc() +{ + TYPE_STRUCT_PTR parm_tp; /* actual param type */ + + if (token == LPAREN) { + get_token(); + parm_tp = base_type(expression()); + + if (parm_tp != real_typep) { + error(INCOMPATIBLE_TYPES); + } + + if_token_get_else_error(RPAREN, MISSING_RPAREN); + } + else error(WRONG_NUMBER_OF_PARMS); + + return(integer_typep); +} /* end round_trunc */ +/***************************************************************************/ + + + +/***************************************************************************/ +/* insert_etc Process a call to INSERT, etc */ +/* list procedures */ +/* INSERT(LIST, GENERIC, INTEGER) */ +/* REMOVE(LIST, INTEGER) */ + +insert_etc(rtn_idp) +SYMTAB_NODE_PTR rtn_idp; +{ + TYPE_STRUCT_PTR parm_tp; /* actual parm type */ + + if (token == LPAREN) { + get_token(); + parm_tp = base_type(expression()); + if (parm_tp->form != LIST_FORM) { + error(INCOMPATIBLE_TYPES); + } + if_token_get_else_error(COMMA, MISSING_COMMA); + if (rtn_idp->defn.info.routine.key == XINSERT) { + expression(); + if_token_get_else_error(COMMA, MISSING_COMMA); + } + parm_tp = base_type(expression()); + if (parm_tp != integer_typep) { + error(INCOMPATIBLE_TYPES); + } + if_token_get_else_error(RPAREN, MISSING_RPAREN); + } + else error(WRONG_NUMBER_OF_PARMS); + +} /* end INSERT_ETC */ +/***************************************************************************/ + + + + + + |