From 2ca264f423c2cd5cb7024e12c743692d6a6edbb2 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 13 Feb 2004 23:46:05 +0000 Subject: [PATCH] We compile invsf now. --- mad | 59 +++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/mad b/mad index 06de6e2..026710e 100755 --- a/mad +++ b/mad @@ -1,11 +1,12 @@ #!/usr/bin/env python reserved = ('BOOLEAN', 'CONDITIONAL', 'CONTINUE', 'DATA', 'DIMENSION', - 'END', 'ENTRY', 'EXECUTE', 'EXTERNAL', 'FOR', 'FUNCTION', - 'INTEGER', 'INTERNAL', 'IS', 'MODE', 'NORMAL', - 'OF', 'OR', 'PAUSE', 'PRINT_FORMAT', 'PROGRAM', 'READ_FORMAT', - 'RESTORE', 'RETURN', 'SAVE', 'SET_LIST_TO', 'THROUGH', - 'TO', 'TRANSFER', 'VALUES', 'VECTOR', 'WHENEVER', + 'END', 'ENTRY', 'ERROR', 'EXECUTE', 'EXTERNAL', 'FOR', + 'FUNCTION', 'INTEGER', 'INTERNAL', 'IS', 'MODE', 'NORMAL', + 'OF', 'OR', 'OTHERWISE', 'PAUSE', 'PRINT_FORMAT', + 'PROGRAM', 'READ_FORMAT', 'RESTORE', 'RETURN', 'SAVE', + 'SET_LIST_TO', 'THROUGH', 'TO', 'TRANSFER', 'VALUES', + 'VECTOR', 'WHENEVER', # COMMENT is a pseudo-keyword generated early in compilation. 'COMMENT', 'DOTRANGE') @@ -57,11 +58,15 @@ def t_STRING(t): t.value = t.value[1:-1] return t +def t_FUNCALL(t): + r'[A-Z][A-Z0-9]*\.(?=\s*(\(|eos))' + t.type = reserved_map.get(t.value, 'FUNCALL') + t.value = t.value.lower() + return t + def t_NAME(t): - r'[A-Z][A-Z0-9_]*(\.(?!P))?' + r'[A-Z][A-Z0-9_]*' t.type = reserved_map.get(t.value, 'NAME') - if t.value[-1] == '.': - t.type = 'FUNCALL' t.value = t.value.lower() return t @@ -145,6 +150,10 @@ def p_labeled_card(t): 'card : NAME statement EOS' deck.append((sourcefile, t.lineno(1), t[1], t[2])) +def p_empty_card(t): + 'card : EOS' + pass + # Statement level ## BOOLEAN @@ -191,6 +200,11 @@ def p_entry(t): initfunc(t[3]) t[0] = ('entry', t[3]) +## ERROR RETURN +def p_error_return(t): + "statement : ERROR RETURN" + t[0] = ('error_return',) + ## EXECUTE def p_execute(t): 'statement : EXECUTE FUNCALL application' @@ -248,6 +262,11 @@ def p_typeval_bool(t): "typeval : BOOLEAN" t[0] = 'bool' +## OTHERWISE +def p_otherwise(t): + "statement : OTHERWISE" + t[0] = ('else',) + ## PAUSE def p_pause(t): "statement : PAUSE expression" @@ -432,25 +451,25 @@ def p_expression_subscript(t): refcount[var] = refcount.get(var, 0) + 1 arraydepths[var] = len(t[2]) -def p_function_application(t): - 'expression : FUNCALL application' - t[0] = ('apply', t[1], tuple(t[2])) - global headers - if t[1] in ('elog.', 'sqrt.') and "math" not in headers: - headers.append("math") - -def p_expression_application(t): +def p_application(t): 'application : LPAREN arglist RPAREN' t[0] = t[2] -def p_expression_tail_empty(t): +def p_application_tail_empty(t): 'arglist : expression' t[0] = [t[1]] -def p_expression_tail_nonempty(t): +def p_application_tail_nonempty(t): 'arglist : arglist COMMA expression' t[0] = t[1] + [t[3]] +def p_function_application(t): + 'expression : FUNCALL application' + t[0] = ('apply', t[1], tuple(t[2])) + global headers + if t[1] in ('elog.', 'sqrt.') and "math" not in headers: + headers.append("math") + def p_expression_name(t): 'expression : NAME' var = t[1] @@ -831,6 +850,8 @@ def print_C_statement(statement): if mad_debug: rep += " /* %s */" % statement[0] return rep + elif statement[0] == 'else': + return "} else {" elif statement[0] == 'entry': currentfunc = statement[1] types = typedict[currentfunc] @@ -864,6 +885,8 @@ def print_C_statement(statement): if declarations: rep += " " + declarations[:-1] + "\n" return rep + elif statement[0] == 'error_return': + return 'puts("ERROR RETURN"); exit(1);' elif statement[0] == 'execute': return print_C_expr(statement[1]) + ";" elif statement[0] == 'external_call': -- 2.43.0