Ejemplo n.º 1
0
// Clear dynamic buffer, then append to it until an illegal (for a keyword)
// character is read. Zero-terminate the string. Return its length (without
// terminator).
// Zero lengths will produce a "missing string" error.
int Input_read_keyword(void) {
	int	length;

	DYNABUF_CLEAR(GlobalDynaBuf);
	length = Input_append_keyword_to_global_dynabuf();
	// add terminator to buffer (increments buffer's length counter)
	DynaBuf_append(GlobalDynaBuf, '\0');
	return(length);
}
Ejemplo n.º 2
0
Archivo: macro.c Proyecto: lhz/acme
// This function is only called during the first pass, so there's no need to
// check whether to skip the definition or not.
// Return with GotByte = '}'
void Macro_parse_definition(void)	// Now GotByte = illegal char after "!macro"
{
    char		*formal_parameters;
    struct rwnode	*macro_node;
    struct macro	*new_macro;
    zone_t		macro_zone	= get_zone_and_title();

    // now GotByte = first non-space after title
    DYNABUF_CLEAR(GlobalDynaBuf);	// prepare to hold formal parameters
    // GlobalDynaBuf = "" (will hold formal parameter list)
    // user_macro_name = [LOCAL_PREFIX] MacroTitle NUL
    // internal_name = MacroTitle ARG_SEPARATOR (grows to signature)
    // Accept n>=0 comma-separated formal parameters before CHAR_SOB ('{').
    // Valid argument formats are:
    // .LOCAL_LABEL_BY_VALUE
    // ~.LOCAL_LABEL_BY_REFERENCE
    // GLOBAL_LABEL_BY_VALUE	global args are very uncommon,
    // ~GLOBAL_LABEL_BY_REFERENCE	but not forbidden
    // now GotByte = non-space
    if (GotByte != CHAR_SOB) {	// any at all?
        do {
            // handle call-by-reference character ('~')
            if (GotByte != REFERENCE_CHAR) {
                DynaBuf_append(internal_name, ARGTYPE_NUM_VAL);
            } else {
                DynaBuf_append(internal_name, ARGTYPE_NUM_REF);
                DynaBuf_append(GlobalDynaBuf, REFERENCE_CHAR);
                GetByte();
            }
            // handle prefix for local symbols (LOCAL_PREFIX, normally '.')
            if (GotByte == LOCAL_PREFIX) {
                DynaBuf_append(GlobalDynaBuf, LOCAL_PREFIX);
                GetByte();
            }
            // handle symbol name
            Input_append_keyword_to_global_dynabuf();
        } while (pipe_comma());
        // ensure CHAR_SOB ('{')
        if (GotByte != CHAR_SOB)
            Throw_serious_error(exception_no_left_brace);
    }
    DynaBuf_append(GlobalDynaBuf, CHAR_EOS);	// terminate param list
    // now GlobalDynaBuf = comma-separated parameter list without spaces,
    // but terminated with CHAR_EOS.
    formal_parameters = DynaBuf_get_copy(GlobalDynaBuf);
    // now GlobalDynaBuf = unused
    // Reading the macro body would change the line number. To have correct
    // error messages, we're checking for "macro twice" *now*.
    // Search for macro. Create if not found.
    // But if found, complain (macro twice).
    if (search_for_macro(&macro_node, macro_zone, TRUE) == FALSE)
        report_redefinition(macro_node);	// quits with serious error
    // Create new macro struct and set it up. Finally we'll read the body.
    new_macro = safe_malloc(sizeof(*new_macro));
    new_macro->def_line_number = Input_now->line_number;
    new_macro->def_filename = get_string_copy(Input_now->original_filename);
    new_macro->original_name = get_string_copy(user_macro_name->buffer);
    new_macro->parameter_list = formal_parameters;
    new_macro->body = Input_skip_or_store_block(TRUE);	// changes LineNumber
    macro_node->body = new_macro;	// link macro struct to tree node
    // and that about sums it up
}