/* ============ PR_ParseImmediateStatements Parse a function body ============ */ function_t *PR_ParseImmediateStatements (type_t *type) { int i; function_t *f; def_t *defs[MAX_PARMS]; f = malloc (sizeof(function_t)); // // check for builtin function definition #1, #2, etc // if (PR_Check ("#")) { if (pr_token_type != tt_immediate || pr_immediate_type != &type_float || pr_immediate._float != (int)pr_immediate._float) PR_ParseError ("Bad builtin immediate"); f->builtin = (int)pr_immediate._float; PR_Lex (); return f; } f->builtin = 0; // // define the parms // for (i=0 ; i<type->num_parms ; i++) { defs[i] = PR_GetDef (type->parm_types[i], pr_parm_names[i], pr_scope, true); f->parm_ofs[i] = defs[i]->ofs; if (i > 0 && f->parm_ofs[i] < f->parm_ofs[i-1]) Error ("bad parm order"); } f->code = numstatements; // // check for a state opcode // if (PR_Check ("[")) PR_ParseState (); // // parse regular statements // PR_Expect ("{"); while (!PR_Check("}")) PR_ParseStatement (); // emit an end of statements opcode PR_Statement (pr_opcodes, 0,0); return f; }
/* ============ PR_ParseStatement ============ */ void PR_ParseStatement (void) { def_t *e; dstatement_t *patch1, *patch2; if (PR_Check ("{")) { do { PR_ParseStatement (); } while (!PR_Check ("}")); return; } if (PR_Check("return")) { if (PR_Check (";")) { PR_Statement (&pr_opcodes[OP_RETURN], 0, 0); return; } e = PR_Expression (TOP_PRIORITY); PR_Expect (";"); PR_Statement (&pr_opcodes[OP_RETURN], e, 0); return; } if (PR_Check("while")) { PR_Expect ("("); patch2 = &statements[numstatements]; e = PR_Expression (TOP_PRIORITY); PR_Expect (")"); patch1 = &statements[numstatements]; PR_Statement (&pr_opcodes[OP_IFNOT], e, 0); PR_ParseStatement (); junkdef.ofs = patch2 - &statements[numstatements]; PR_Statement (&pr_opcodes[OP_GOTO], &junkdef, 0); patch1->b = &statements[numstatements] - patch1; return; } if (PR_Check("do")) { patch1 = &statements[numstatements]; PR_ParseStatement (); PR_Expect ("while"); PR_Expect ("("); e = PR_Expression (TOP_PRIORITY); PR_Expect (")"); PR_Expect (";"); junkdef.ofs = patch1 - &statements[numstatements]; PR_Statement (&pr_opcodes[OP_IF], e, &junkdef); return; } if (PR_Check("local")) { PR_ParseDefs (); locals_end = numpr_globals; return; } if (PR_Check("if")) { PR_Expect ("("); e = PR_Expression (TOP_PRIORITY); PR_Expect (")"); patch1 = &statements[numstatements]; PR_Statement (&pr_opcodes[OP_IFNOT], e, 0); PR_ParseStatement (); if (PR_Check ("else")) { patch2 = &statements[numstatements]; PR_Statement (&pr_opcodes[OP_GOTO], 0, 0); patch1->b = &statements[numstatements] - patch1; PR_ParseStatement (); patch2->a = &statements[numstatements] - patch2; } else patch1->b = &statements[numstatements] - patch1; return; } PR_Expression (TOP_PRIORITY); PR_Expect (";"); }
/* ============ PR_ParseStatement ============ */ void PR_ParseStatement (void) { def_t *e = NULL; dstatement_t *patch1 = NULL; dstatement_t *patch2 = NULL; if (PR_Check(";")) return; if (PR_Check ("{")) { while (!PR_Check ("}")) PR_ParseStatement (); return; } if (PR_Check("return")) { if (PR_Check (";")) { PR_Statement (&pr_opcodes[OP_RETURN], 0, 0); return; } e = PR_Expression (TOP_PRIORITY); PR_Expect (";"); PR_Statement (&pr_opcodes[OP_RETURN], e, 0); return; } if (PR_Check("while")) { PR_Expect ("("); patch2 = &statements[numstatements]; e = PR_Expression (TOP_PRIORITY); PR_Expect (")"); patch1 = &statements[numstatements]; PR_Statement (&pr_opcodes[OP_IFNOT], e, 0); PR_ParseStatement (); junkdef.ofs = patch2 - &statements[numstatements]; PR_Statement (&pr_opcodes[OP_GOTO], &junkdef, 0); patch1->b = (unsigned short)(&statements[numstatements] - patch1); return; } if (PR_Check("do")) { patch1 = &statements[numstatements]; PR_ParseStatement (); PR_Expect ("while"); PR_Expect ("("); e = PR_Expression (TOP_PRIORITY); PR_Expect (")"); PR_Expect (";"); junkdef.ofs = patch1 - &statements[numstatements]; PR_Statement (&pr_opcodes[OP_IF], e, &junkdef); return; } if ( PR_Check("local") || !strcmp(pr_token, "const") || !strcmp(pr_token, "float") || !strcmp(pr_token, "vector") || !strcmp(pr_token, "entity") || !strcmp(pr_token, "string") || !strcmp(pr_token, "void")) { PR_ParseDefs (); locals_end = numpr_globals; return; } if (PR_Check("if")) { PR_Expect ("("); e = PR_Expression (TOP_PRIORITY); PR_Expect (")"); patch1 = &statements[numstatements]; PR_Statement (&pr_opcodes[OP_IFNOT], e, 0); PR_ParseStatement (); if (PR_Check ("else")) { patch2 = &statements[numstatements]; PR_Statement (&pr_opcodes[OP_GOTO], 0, 0); patch1->b = (unsigned short)(&statements[numstatements] - patch1); PR_ParseStatement (); patch2->a = (unsigned short)(&statements[numstatements] - patch2); } else patch1->b = (unsigned short)(&statements[numstatements] - patch1); return; } if (PR_Check("else")) PR_ParseError ("illegal else without matching if"); PR_Expression (TOP_PRIORITY); PR_Expect (";"); }