1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
/**
** Ucfun.h - Usecode compiler function.
**
** Written: 1/2/01 - JSF
**/
/*
Copyright (C) 2000 The Exult Team
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 the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef INCL_UCFUN
#define INCL_UCFUN
#include "ucsym.h"
#include "uclabel.h"
class Uc_statement;
#ifndef ALPHA_LINUX_CXX
# include <iosfwd>
#endif
/*
* This represents a usecode function:
*/
class Uc_function
{
static Uc_scope globals; // For finding intrinsics, funs.
// Intrinsics, indexed by number:
static vector<Uc_intrinsic_symbol *> intrinsics;
Uc_scope top; // Top-level scope.
Uc_function_symbol *proto; // Function declaration.
Uc_scope *cur_scope; // Current scope.
int num_parms; // # parameters.
int num_locals; // Counts locals.
// Stack of loops (where 'break' can
// be used.
vector<Uc_statement *> breakables;
vector<int> breaks; // Offsets of generated breaks in
// current loop, with loops separated
// by -1's.
// Links to called functions:
std::vector<Uc_function_symbol *> links;
std::map<std::string, Uc_label *> labels;
char *text_data; // All strings.
int text_data_size;
Uc_statement *statement; // Statement(s) in function.
int reloffset; // relative offset of the code being generated
public:
Uc_function(Uc_function_symbol *p);
~Uc_function();
enum Intrinsic_type
{
bg, // Black gate.
si // Serpent isle.
};
static void set_intrinsics(Intrinsic_type ty);
void set_statement(Uc_statement *s)
{ statement = s; }
void adjust_reloffset(int diff) { reloffset += diff; }
int get_reloffset() const { return reloffset; }
void push_scope() // Start a new scope.
{ cur_scope = cur_scope->add_scope(); }
void pop_scope() // End scope.
{
cur_scope = cur_scope->get_parent();
}
Uc_symbol *search(char *nm) // Search current scope.
{ return cur_scope->search(nm); }
Uc_symbol *search_up(char *nm)
{
Uc_symbol *sym = cur_scope->search_up(nm);
return (sym ? sym : globals.search(nm));
}
static Uc_intrinsic_symbol *get_intrinsic(int i)
{ return (i >= 0 && i < intrinsics.size())? intrinsics[i] : 0;}
// Already declared?
static bool is_dup(Uc_scope *scope, char *nm);
Uc_var_symbol *add_symbol(char *nm);// Add var. to current scope.
int add_function_symbol(Uc_function_symbol *fun)
{ return cur_scope->add_function_symbol(fun); }
static int add_global_function_symbol(Uc_function_symbol *fun)
{ return globals.add_function_symbol(fun); }
// Add string constant.
Uc_symbol *add_string_symbol(char *nm, char *text);
// Add int constant.
Uc_symbol *add_int_const_symbol(char *nm, int value);
static Uc_symbol *add_global_int_const_symbol(char *nm, int val);
int add_string(char *text);
// Start/end loop.
void add_label(Uc_label* l) { labels[l->get_name()] = l; }
Uc_label *search_label(char *nm);
void start_breakable(Uc_statement *s);
void end_breakable(Uc_statement *s, vector<char>& stmt_code);
// Store 'break' location.
void add_break(int op_offset); // DANGER: Offset is filled in when
// end_breakable() is called, so the
// string this is in better not have
// been deleted!!!
// Link external function.
int link(Uc_function_symbol *fun);
void link_labels(std::vector<char>& code);
void gen(std::ostream& out); // Generate Usecode.
};
#endif
|