/* ============ PR_CompileFile compiles the 0 terminated text, adding defintions to the pr structure ============ */ qboolean PR_CompileFile (char *string, char *filename) { if (!pr.memory) Error ("PR_CompileFile: Didn't clear"); PR_ClearGrabMacros (); // clear the frame macros pr_file_p = string; s_file = CopyString (filename); pr_source_line = 0; PR_NewLine (); PR_Lex (); // read first token while (pr_token_type != tt_eof) { if (setjmp(pr_parse_abort)) { if (++pr_error_count > MAX_ERRORS) return false; PR_SkipToSemicolon (); if (pr_token_type == tt_eof) return false; } pr_scope = NULL; // outside all functions PR_ParseDefs (); } return (pr_error_count == 0); }
/* ============ 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 (";"); }