mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-05-31 08:41:11 +00:00
rework the param parsing to make selectors easier to handle
This commit is contained in:
parent
d5b637ae06
commit
b226d24b52
9 changed files with 293 additions and 194 deletions
51
tools/qfcc/include/function.h
Normal file
51
tools/qfcc/include/function.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
#FILENAME#
|
||||||
|
|
||||||
|
#DESCRIPTION#
|
||||||
|
|
||||||
|
Copyright (C) 2001 #AUTHOR#
|
||||||
|
|
||||||
|
Author: #AUTHOR#
|
||||||
|
Date: #DATE#
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to:
|
||||||
|
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
59 Temple Place - Suite 330
|
||||||
|
Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
$Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __function_h
|
||||||
|
#define __function_h
|
||||||
|
|
||||||
|
typedef struct param_s {
|
||||||
|
struct param_s *next;
|
||||||
|
const char *selector;
|
||||||
|
type_t *type;
|
||||||
|
const char *name;
|
||||||
|
} param_t;
|
||||||
|
|
||||||
|
param_t *new_param (const char *selector, type_t *type, const char *name);
|
||||||
|
|
||||||
|
type_t *parse_params (type_t *type, param_t *params);
|
||||||
|
void build_scope (function_t *f, def_t *func, param_t *params);
|
||||||
|
function_t *new_function (void);
|
||||||
|
void build_function (function_t *f);
|
||||||
|
void finish_function (function_t *f);
|
||||||
|
void emit_function (function_t *f, expr_t *e);
|
||||||
|
|
||||||
|
#endif//__function_h
|
|
@ -331,11 +331,6 @@ typedef struct def_s {
|
||||||
struct def_s *parent; // vector/quaternion member
|
struct def_s *parent; // vector/quaternion member
|
||||||
} def_t;
|
} def_t;
|
||||||
|
|
||||||
typedef struct param_s {
|
|
||||||
def_t *params;
|
|
||||||
int elipsis;
|
|
||||||
} param_t;
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
// pr_loc.h -- program local defs
|
// pr_loc.h -- program local defs
|
||||||
|
@ -502,7 +497,6 @@ void PR_PrintDefs (void);
|
||||||
void PR_PrintFunction (def_t *def);
|
void PR_PrintFunction (def_t *def);
|
||||||
void PR_SkipToSemicolon (void);
|
void PR_SkipToSemicolon (void);
|
||||||
|
|
||||||
extern char pr_parm_names[MAX_PARMS][MAX_NAME];
|
|
||||||
extern qboolean pr_trace;
|
extern qboolean pr_trace;
|
||||||
|
|
||||||
#define G_FLOAT(o) (pr_globals[o])
|
#define G_FLOAT(o) (pr_globals[o])
|
||||||
|
|
|
@ -37,7 +37,7 @@ YFLAGS = -d
|
||||||
|
|
||||||
bin_PROGRAMS= qfcc
|
bin_PROGRAMS= qfcc
|
||||||
|
|
||||||
qfcc_SOURCES= cmdlib.c debug.c pr_comp.c pr_def.c pr_imm.c pr_lex.c pr_opcode.c qfcc.c qc-parse.y qc-lex.l emit.c expr.c struct.c switch.c type.c
|
qfcc_SOURCES= cmdlib.c debug.c pr_comp.c pr_def.c pr_imm.c pr_lex.c pr_opcode.c qfcc.c qc-parse.y qc-lex.l emit.c expr.c function.c struct.c switch.c type.c
|
||||||
qfcc_LDADD= $(QFCC_LIBS)
|
qfcc_LDADD= $(QFCC_LIBS)
|
||||||
qfcc_DEPENDENCIES= $(QFCC_DEPS)
|
qfcc_DEPENDENCIES= $(QFCC_DEPS)
|
||||||
EXTRA_DIST= qc-parse.h
|
EXTRA_DIST= qc-parse.h
|
||||||
|
|
|
@ -37,6 +37,7 @@ static const char rcsid[] =
|
||||||
#include <QF/va.h>
|
#include <QF/va.h>
|
||||||
|
|
||||||
#include "qfcc.h"
|
#include "qfcc.h"
|
||||||
|
#include "function.h"
|
||||||
#include "struct.h"
|
#include "struct.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "qc-parse.h"
|
#include "qc-parse.h"
|
||||||
|
|
204
tools/qfcc/source/function.c
Normal file
204
tools/qfcc/source/function.c
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
/*
|
||||||
|
function.c
|
||||||
|
|
||||||
|
QC function support code
|
||||||
|
|
||||||
|
Copyright (C) 2001 Bill Currie
|
||||||
|
|
||||||
|
Author: Bill Currie <bill@taniwha.org>
|
||||||
|
Date: 2002/5/7
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to:
|
||||||
|
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
59 Temple Place - Suite 330
|
||||||
|
Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
*/
|
||||||
|
static const char rcsid[] =
|
||||||
|
"$Id$";
|
||||||
|
|
||||||
|
#include "qfcc.h"
|
||||||
|
|
||||||
|
#include "function.h"
|
||||||
|
#include "type.h"
|
||||||
|
|
||||||
|
param_t *
|
||||||
|
new_param (const char *selector, type_t *type, const char *name)
|
||||||
|
{
|
||||||
|
param_t *param = malloc (sizeof (param_t));
|
||||||
|
|
||||||
|
param->next = 0;
|
||||||
|
param->selector = selector;
|
||||||
|
param->type = type;
|
||||||
|
param->name = name;
|
||||||
|
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
type_t *
|
||||||
|
parse_params (type_t *type, param_t *parms)
|
||||||
|
{
|
||||||
|
int ellipsis = 0, i;
|
||||||
|
param_t *p;
|
||||||
|
type_t new;
|
||||||
|
|
||||||
|
memset (&new, 0, sizeof (new));
|
||||||
|
new.type = ev_func;
|
||||||
|
new.aux_type = type;
|
||||||
|
new.num_parms = 0;
|
||||||
|
|
||||||
|
if (parms && !parms->selector && !parms->type && !parms->name) {
|
||||||
|
ellipsis = 1;
|
||||||
|
parms = parms->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ellipsis) {
|
||||||
|
new.num_parms = -1; // variable args
|
||||||
|
} else if (!parms) {
|
||||||
|
} else {
|
||||||
|
for (p = parms; p; p = p->next, new.num_parms++)
|
||||||
|
;
|
||||||
|
if (new.num_parms > MAX_PARMS) {
|
||||||
|
error (0, "too many params");
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
i = 1;
|
||||||
|
do {
|
||||||
|
//puts (parms->name);
|
||||||
|
new.parm_types[new.num_parms - i] = parms->type;
|
||||||
|
i++;
|
||||||
|
parms = parms->next;
|
||||||
|
} while (parms);
|
||||||
|
}
|
||||||
|
//print_type (&new); puts("");
|
||||||
|
return PR_FindType (&new);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
build_scope (function_t *f, def_t *func, param_t *params)
|
||||||
|
{
|
||||||
|
int i, count;
|
||||||
|
def_t *def;
|
||||||
|
param_t **param_list, *p;
|
||||||
|
|
||||||
|
for (p = params, count = 0; p; p = p->next, count++)
|
||||||
|
;
|
||||||
|
param_list = alloca (sizeof (param_t *) * i);
|
||||||
|
i = count;
|
||||||
|
for (p = params; p; p = p->next)
|
||||||
|
param_list[--i] = p;
|
||||||
|
|
||||||
|
func->alloc = &func->locals;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (!param_list[i]->selector
|
||||||
|
&& !param_list[i]->type
|
||||||
|
&& !param_list[i]->name)
|
||||||
|
continue; // ellipsis marker
|
||||||
|
def = PR_GetDef (param_list[i]->type, param_list[i]->name,
|
||||||
|
func, func->alloc);
|
||||||
|
f->parm_ofs[i] = def->ofs;
|
||||||
|
if (i > 0 && f->parm_ofs[i] < f->parm_ofs[i - 1])
|
||||||
|
Error ("bad parm order");
|
||||||
|
def->used = 1; // don't warn for unused params
|
||||||
|
PR_DefInitialized (def); // params are assumed to be initialized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function_t *
|
||||||
|
new_function (void)
|
||||||
|
{
|
||||||
|
function_t *f;
|
||||||
|
|
||||||
|
f = calloc (1, sizeof (function_t));
|
||||||
|
f->next = pr_functions;
|
||||||
|
pr_functions = f;
|
||||||
|
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
build_function (function_t *f)
|
||||||
|
{
|
||||||
|
f->def->constant = 1;
|
||||||
|
f->def->initialized = 1;
|
||||||
|
G_FUNCTION (f->def->ofs) = numfunctions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
finish_function (function_t *f)
|
||||||
|
{
|
||||||
|
dfunction_t *df;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// fill in the dfunction
|
||||||
|
df = &functions[numfunctions];
|
||||||
|
numfunctions++;
|
||||||
|
f->dfunc = df;
|
||||||
|
|
||||||
|
if (f->builtin)
|
||||||
|
df->first_statement = -f->builtin;
|
||||||
|
else
|
||||||
|
df->first_statement = f->code;
|
||||||
|
|
||||||
|
df->s_name = ReuseString (f->def->name);
|
||||||
|
df->s_file = s_file;
|
||||||
|
df->numparms = f->def->type->num_parms;
|
||||||
|
df->locals = f->def->locals;
|
||||||
|
df->parm_start = 0;
|
||||||
|
for (i = 0; i < df->numparms; i++)
|
||||||
|
df->parm_size[i] = pr_type_size[f->def->type->parm_types[i]->type];
|
||||||
|
|
||||||
|
if (f->aux) {
|
||||||
|
def_t *def;
|
||||||
|
f->aux->function = df - functions;
|
||||||
|
for (def = f->def->scope_next; def; def = def->scope_next) {
|
||||||
|
if (def->name) {
|
||||||
|
ddef_t *d = new_local ();
|
||||||
|
d->type = def->type->type;
|
||||||
|
d->ofs = def->ofs;
|
||||||
|
d->s_name = ReuseString (def->name);
|
||||||
|
|
||||||
|
f->aux->num_locals++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
emit_function (function_t *f, expr_t *e)
|
||||||
|
{
|
||||||
|
//printf (" %s =\n", f->def->name);
|
||||||
|
|
||||||
|
if (f->aux)
|
||||||
|
lineno_base = f->aux->source_line;
|
||||||
|
|
||||||
|
pr_scope = f->def;
|
||||||
|
while (e) {
|
||||||
|
//printf ("%d ", pr_source_line);
|
||||||
|
//print_expr (e);
|
||||||
|
//puts("");
|
||||||
|
|
||||||
|
emit_expr (e);
|
||||||
|
e = e->next;
|
||||||
|
}
|
||||||
|
emit_statement (pr_source_line, op_done, 0, 0, 0);
|
||||||
|
PR_FlushScope (pr_scope, 0);
|
||||||
|
pr_scope = 0;
|
||||||
|
PR_ResetTempDefs ();
|
||||||
|
|
||||||
|
//puts ("");
|
||||||
|
}
|
|
@ -34,11 +34,10 @@ static const char rcsid[] =
|
||||||
#include <QF/sys.h>
|
#include <QF/sys.h>
|
||||||
|
|
||||||
#include "qfcc.h"
|
#include "qfcc.h"
|
||||||
|
#include "function.h"
|
||||||
|
|
||||||
int pr_source_line;
|
int pr_source_line;
|
||||||
|
|
||||||
char pr_parm_names[MAX_PARMS][MAX_NAME];
|
|
||||||
|
|
||||||
char *pr_file_p;
|
char *pr_file_p;
|
||||||
char *pr_line_start; // start of current source line
|
char *pr_line_start; // start of current source line
|
||||||
|
|
||||||
|
|
|
@ -172,7 +172,7 @@ m ([\-+]?)
|
||||||
return yytext[0];
|
return yytext[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
"..." return ELIPSIS;
|
"..." return ELLIPSIS;
|
||||||
|
|
||||||
"<<" return SHL;
|
"<<" return SHL;
|
||||||
">>" return SHR;
|
">>" return SHR;
|
||||||
|
|
|
@ -35,6 +35,7 @@ static const char rcsid[] =
|
||||||
#include <QF/hash.h>
|
#include <QF/hash.h>
|
||||||
#include <QF/sys.h>
|
#include <QF/sys.h>
|
||||||
|
|
||||||
|
#include "function.h"
|
||||||
#include "struct.h"
|
#include "struct.h"
|
||||||
#include "switch.h"
|
#include "switch.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
|
@ -54,12 +55,6 @@ yyerror (const char *s)
|
||||||
int yylex (void);
|
int yylex (void);
|
||||||
type_t *PR_FindType (type_t *new);
|
type_t *PR_FindType (type_t *new);
|
||||||
|
|
||||||
type_t *parse_params (type_t *type, def_t *parms, int elipsis);
|
|
||||||
function_t *new_function (void);
|
|
||||||
void build_function (function_t *f);
|
|
||||||
void finish_function (function_t *f);
|
|
||||||
void emit_function (function_t *f, expr_t *e);
|
|
||||||
void build_scope (function_t *f, def_t *func);
|
|
||||||
type_t *build_type (int is_field, type_t *type);
|
type_t *build_type (int is_field, type_t *type);
|
||||||
type_t *build_array_type (type_t *type, int size);
|
type_t *build_array_type (type_t *type, int size);
|
||||||
|
|
||||||
|
@ -89,7 +84,7 @@ typedef struct {
|
||||||
float quaternion_val[4];
|
float quaternion_val[4];
|
||||||
function_t *function;
|
function_t *function;
|
||||||
struct switch_block_s *switch_block;
|
struct switch_block_s *switch_block;
|
||||||
param_t params;
|
struct param_s *param;
|
||||||
}
|
}
|
||||||
|
|
||||||
%right <op> '=' ASX PAS /* pointer assign */
|
%right <op> '=' ASX PAS /* pointer assign */
|
||||||
|
@ -108,7 +103,7 @@ typedef struct {
|
||||||
%token <vector_val> VECTOR_VAL
|
%token <vector_val> VECTOR_VAL
|
||||||
%token <quaternion_val> QUATERNION_VAL
|
%token <quaternion_val> QUATERNION_VAL
|
||||||
|
|
||||||
%token LOCAL RETURN WHILE DO IF ELSE FOR BREAK CONTINUE ELIPSIS NIL
|
%token LOCAL RETURN WHILE DO IF ELSE FOR BREAK CONTINUE ELLIPSIS NIL
|
||||||
%token IFBE IFB IFAE IFA
|
%token IFBE IFB IFAE IFA
|
||||||
%token SWITCH CASE DEFAULT STRUCT ENUM TYPEDEF
|
%token SWITCH CASE DEFAULT STRUCT ENUM TYPEDEF
|
||||||
%token ELE_START
|
%token ELE_START
|
||||||
|
@ -118,9 +113,10 @@ typedef struct {
|
||||||
%token PROTOCOL PUBLIC SELECTOR
|
%token PROTOCOL PUBLIC SELECTOR
|
||||||
|
|
||||||
%type <type> type type_name
|
%type <type> type type_name
|
||||||
%type <params> function_decl
|
%type <param> function_decl
|
||||||
%type <integer_val> array_decl
|
%type <integer_val> array_decl
|
||||||
%type <def> param param_list def_name
|
%type <param> param param_list
|
||||||
|
%type <def> def_name
|
||||||
%type <def> def_item def_list
|
%type <def> def_item def_list
|
||||||
%type <expr> const opt_expr expr arg_list element_list element_list1 element
|
%type <expr> const opt_expr expr arg_list element_list element_list1 element
|
||||||
%type <expr> string_val opt_state_expr
|
%type <expr> string_val opt_state_expr
|
||||||
|
@ -131,6 +127,8 @@ typedef struct {
|
||||||
%type <switch_block> switch_block
|
%type <switch_block> switch_block
|
||||||
%type <scope> param_scope
|
%type <scope> param_scope
|
||||||
|
|
||||||
|
%type <string_val> selector
|
||||||
|
|
||||||
%expect 1
|
%expect 1
|
||||||
|
|
||||||
%{
|
%{
|
||||||
|
@ -138,6 +136,7 @@ typedef struct {
|
||||||
type_t *current_type;
|
type_t *current_type;
|
||||||
def_t *current_def;
|
def_t *current_def;
|
||||||
function_t *current_func;
|
function_t *current_func;
|
||||||
|
param_t *current_params;
|
||||||
expr_t *local_expr;
|
expr_t *local_expr;
|
||||||
expr_t *break_label;
|
expr_t *break_label;
|
||||||
expr_t *continue_label;
|
expr_t *continue_label;
|
||||||
|
@ -218,7 +217,8 @@ type
|
||||||
| type array_decl { $$ = build_type (0, build_array_type ($1, $2)); }
|
| type array_decl { $$ = build_type (0, build_array_type ($1, $2)); }
|
||||||
| type_name function_decl
|
| type_name function_decl
|
||||||
{
|
{
|
||||||
$$ = build_type (0, parse_params ($1, $2.params, $2.elipsis));
|
current_params = $2;
|
||||||
|
$$ = build_type (0, parse_params ($1, $2));
|
||||||
}
|
}
|
||||||
| type_name { $$ = build_type (0, $1); }
|
| type_name { $$ = build_type (0, $1); }
|
||||||
| '(' type ')' { $$ = $2; }
|
| '(' type ')' { $$ = $2; }
|
||||||
|
@ -236,26 +236,23 @@ function_decl
|
||||||
}
|
}
|
||||||
')'
|
')'
|
||||||
{
|
{
|
||||||
$$.params = $3;
|
$$ = $3;
|
||||||
$$.elipsis = 0;
|
|
||||||
}
|
}
|
||||||
| '(' param_scope param_list ',' ELIPSIS ')'
|
| '(' param_scope param_list ',' ELLIPSIS ')'
|
||||||
{
|
{
|
||||||
PR_FlushScope (pr_scope, 1);
|
PR_FlushScope (pr_scope, 1);
|
||||||
pr_scope = $<scope>2;
|
pr_scope = $<scope>2;
|
||||||
|
|
||||||
$$.params = $3;
|
$$ = new_param (0, 0, 0);
|
||||||
$$.elipsis = 1;
|
$$->next = $3;
|
||||||
}
|
}
|
||||||
| '(' ELIPSIS ')'
|
| '(' ELLIPSIS ')'
|
||||||
{
|
{
|
||||||
$$.params = 0;
|
$$ = new_param (0, 0, 0);
|
||||||
$$.elipsis = 1;
|
|
||||||
}
|
}
|
||||||
| '(' ')'
|
| '(' ')'
|
||||||
{
|
{
|
||||||
$$.params = 0;
|
$$ = 0;
|
||||||
$$.elipsis = 0;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -273,22 +270,13 @@ param_list
|
||||||
: param
|
: param
|
||||||
| param_list ',' param
|
| param_list ',' param
|
||||||
{
|
{
|
||||||
if ($3->next) {
|
$3->next = $1;
|
||||||
error (0, "parameter redeclared: %s", $3->name);
|
$$ = $3;
|
||||||
$$ = $1;
|
|
||||||
} else {
|
|
||||||
$3->next = $1;
|
|
||||||
$$ = $3;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
param
|
param
|
||||||
: type {current_type = $1;} def_name
|
: type NAME { $$ = new_param (0, $1, $2); }
|
||||||
{
|
|
||||||
$3->type = $1;
|
|
||||||
$$ = $3;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
array_decl
|
array_decl
|
||||||
|
@ -493,7 +481,7 @@ begin_function
|
||||||
lineno->fa.func = $$->aux - auxfunctions;
|
lineno->fa.func = $$->aux - auxfunctions;
|
||||||
}
|
}
|
||||||
pr_scope = current_def;
|
pr_scope = current_def;
|
||||||
build_scope ($$, current_def);
|
build_scope ($$, current_def, current_params);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -980,11 +968,11 @@ methoddecl
|
||||||
|
|
||||||
optparmlist
|
optparmlist
|
||||||
: /* empty */
|
: /* empty */
|
||||||
| ',' ELIPSIS
|
| ',' ELLIPSIS
|
||||||
;
|
;
|
||||||
|
|
||||||
unaryselector
|
unaryselector
|
||||||
: selector
|
: selector { /* XXX */ }
|
||||||
;
|
;
|
||||||
|
|
||||||
keywordselector
|
keywordselector
|
||||||
|
@ -993,18 +981,18 @@ keywordselector
|
||||||
;
|
;
|
||||||
|
|
||||||
selector
|
selector
|
||||||
: NAME { /* XXX */ }
|
: NAME
|
||||||
;
|
;
|
||||||
|
|
||||||
keyworddecl
|
keyworddecl
|
||||||
: selector ':' '(' type ')' NAME
|
: selector ':' '(' type ')' NAME { /* XXX */ }
|
||||||
| selector ':' NAME
|
| selector ':' NAME { /* XXX */ }
|
||||||
| ':' '(' type ')' NAME
|
| ':' '(' type ')' NAME { /* XXX */ }
|
||||||
| ':' NAME
|
| ':' NAME { /* XXX */ }
|
||||||
;
|
;
|
||||||
|
|
||||||
messageargs
|
messageargs
|
||||||
: selector
|
: selector { /* XXX */ }
|
||||||
| keywordarglist
|
| keywordarglist
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -1018,7 +1006,7 @@ keywordexpr
|
||||||
;
|
;
|
||||||
|
|
||||||
keywordarg
|
keywordarg
|
||||||
: selector ':' keywordexpr
|
: selector ':' keywordexpr { /* XXX */ }
|
||||||
| ':' keywordexpr
|
| ':' keywordexpr
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -1039,7 +1027,7 @@ obj_messageexpr
|
||||||
;
|
;
|
||||||
|
|
||||||
selectorarg
|
selectorarg
|
||||||
: selector
|
: selector { /* XXX */ }
|
||||||
| keywordnamelist
|
| keywordnamelist
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -1049,7 +1037,7 @@ keywordnamelist
|
||||||
;
|
;
|
||||||
|
|
||||||
keywordname
|
keywordname
|
||||||
: selector ':'
|
: selector ':' { /* XXX */ }
|
||||||
| ':'
|
| ':'
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -1060,60 +1048,6 @@ obj_string
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
type_t *
|
|
||||||
parse_params (type_t *type, def_t *parms, int elipsis)
|
|
||||||
{
|
|
||||||
type_t new;
|
|
||||||
def_t *p;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
memset (&new, 0, sizeof (new));
|
|
||||||
new.type = ev_func;
|
|
||||||
new.aux_type = type;
|
|
||||||
new.num_parms = 0;
|
|
||||||
|
|
||||||
if (elipsis) {
|
|
||||||
new.num_parms = -1; // variable args
|
|
||||||
} else if (!parms) {
|
|
||||||
} else {
|
|
||||||
for (p = parms; p; p = p->next, new.num_parms++)
|
|
||||||
;
|
|
||||||
if (new.num_parms > MAX_PARMS) {
|
|
||||||
error (0, "too many params");
|
|
||||||
return current_type;
|
|
||||||
}
|
|
||||||
i = 1;
|
|
||||||
do {
|
|
||||||
//puts (parms->name);
|
|
||||||
strcpy (pr_parm_names[new.num_parms - i], parms->name);
|
|
||||||
new.parm_types[new.num_parms - i] = parms->type;
|
|
||||||
i++;
|
|
||||||
parms = parms->next;
|
|
||||||
} while (parms);
|
|
||||||
}
|
|
||||||
//print_type (&new); puts("");
|
|
||||||
return PR_FindType (&new);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
build_scope (function_t *f, def_t *func)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
def_t *def;
|
|
||||||
type_t *ftype = func->type;
|
|
||||||
|
|
||||||
func->alloc = &func->locals;
|
|
||||||
|
|
||||||
for (i = 0; i < ftype->num_parms; i++) {
|
|
||||||
def = PR_GetDef (ftype->parm_types[i], pr_parm_names[i], func, func->alloc);
|
|
||||||
f->parm_ofs[i] = def->ofs;
|
|
||||||
if (i > 0 && f->parm_ofs[i] < f->parm_ofs[i - 1])
|
|
||||||
Error ("bad parm order");
|
|
||||||
def->used = 1; // don't warn for unused params
|
|
||||||
PR_DefInitialized (def); // params are assumed to be initialized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type_t *
|
type_t *
|
||||||
build_type (int is_field, type_t *type)
|
build_type (int is_field, type_t *type)
|
||||||
{
|
{
|
||||||
|
@ -1140,91 +1074,6 @@ build_array_type (type_t *type, int size)
|
||||||
return PR_FindType (&new);
|
return PR_FindType (&new);
|
||||||
}
|
}
|
||||||
|
|
||||||
function_t *
|
|
||||||
new_function (void)
|
|
||||||
{
|
|
||||||
function_t *f;
|
|
||||||
|
|
||||||
f = calloc (1, sizeof (function_t));
|
|
||||||
f->next = pr_functions;
|
|
||||||
pr_functions = f;
|
|
||||||
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
build_function (function_t *f)
|
|
||||||
{
|
|
||||||
f->def->constant = 1;
|
|
||||||
f->def->initialized = 1;
|
|
||||||
G_FUNCTION (f->def->ofs) = numfunctions;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
finish_function (function_t *f)
|
|
||||||
{
|
|
||||||
dfunction_t *df;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// fill in the dfunction
|
|
||||||
df = &functions[numfunctions];
|
|
||||||
numfunctions++;
|
|
||||||
f->dfunc = df;
|
|
||||||
|
|
||||||
if (f->builtin)
|
|
||||||
df->first_statement = -f->builtin;
|
|
||||||
else
|
|
||||||
df->first_statement = f->code;
|
|
||||||
|
|
||||||
df->s_name = ReuseString (f->def->name);
|
|
||||||
df->s_file = s_file;
|
|
||||||
df->numparms = f->def->type->num_parms;
|
|
||||||
df->locals = f->def->locals;
|
|
||||||
df->parm_start = 0;
|
|
||||||
for (i = 0; i < df->numparms; i++)
|
|
||||||
df->parm_size[i] = pr_type_size[f->def->type->parm_types[i]->type];
|
|
||||||
|
|
||||||
if (f->aux) {
|
|
||||||
def_t *def;
|
|
||||||
f->aux->function = df - functions;
|
|
||||||
for (def = f->def->scope_next; def; def = def->scope_next) {
|
|
||||||
if (def->name) {
|
|
||||||
ddef_t *d = new_local ();
|
|
||||||
d->type = def->type->type;
|
|
||||||
d->ofs = def->ofs;
|
|
||||||
d->s_name = ReuseString (def->name);
|
|
||||||
|
|
||||||
f->aux->num_locals++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
emit_function (function_t *f, expr_t *e)
|
|
||||||
{
|
|
||||||
//printf (" %s =\n", f->def->name);
|
|
||||||
|
|
||||||
if (f->aux)
|
|
||||||
lineno_base = f->aux->source_line;
|
|
||||||
|
|
||||||
pr_scope = f->def;
|
|
||||||
while (e) {
|
|
||||||
//printf ("%d ", pr_source_line);
|
|
||||||
//print_expr (e);
|
|
||||||
//puts("");
|
|
||||||
|
|
||||||
emit_expr (e);
|
|
||||||
e = e->next;
|
|
||||||
}
|
|
||||||
emit_statement (pr_source_line, op_done, 0, 0, 0);
|
|
||||||
PR_FlushScope (pr_scope, 0);
|
|
||||||
pr_scope = 0;
|
|
||||||
PR_ResetTempDefs ();
|
|
||||||
|
|
||||||
//puts ("");
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
def_t *def;
|
def_t *def;
|
||||||
int state;
|
int state;
|
||||||
|
|
|
@ -35,6 +35,7 @@ static const char rcsid[] =
|
||||||
#include "QF/hash.h"
|
#include "QF/hash.h"
|
||||||
|
|
||||||
#include "qfcc.h"
|
#include "qfcc.h"
|
||||||
|
#include "function.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue