/*
* cola.h
*
* $Id: cola.h 21549 2007-09-25 08:46:12Z paultcochrane $
*
* Cola compiler for Parrot
*
* Copyright (C) 2002 Melvin Smith <melvin.smith@mindspring.com>
*
* The giant, hulking header file.
*/
#ifndef PARROT_LANGUAGES_COLA_H_GUARD
#define PARROT_LANGUAGES_COLA_H_GUARD
# define COLA_VERSION "0.0.11.1"
# define DEBUG 0
void abort(void);
void exit(int status);
enum ASTKIND {
KIND_DECL,
KIND_STATEMENT,
KIND_BLOCK,
KIND_EXPR,
KIND_PARAM
};
enum ASTTYPE {
ASTT_LITERAL,
ASTT_IDENTIFIER,
ASTT_NAMESPACE_DECL,
ASTT_CLASS_DECL,
ASTT_CONSTANT_DECL,
ASTT_FIELD_DECL,
ASTT_METHOD_DECL,
ASTT_FIXED_PARAM,
ASTT_PARAM_ARRAY,
ASTT_ASSIGN,
ASTT_OP,
ASTT_LOGICAL,
ASTT_INDEX,
ASTT_IF,
ASTT_WHILE,
ASTT_FOR,
ASTT_BREAK,
ASTT_CONTINUE,
ASTT_RETURN,
ASTT_GOTO,
ASTT_METHOD_CALL,
ASTT_BOOLEAN,
ASTT_COMPARISON,
ASTT_CONDITIONAL_EXPR,
ASTT_PREINC,
ASTT_POSTINC,
ASTT_NEW_OBJECT
};
enum TYPES {
TYPE_SCALAR,
TYPE_REFERENCE,
TYPE_ARRAY,
TYPE_METHOD,
TYPE_CLASS
};
# define MOD_PUBLIC (1)
# define MOD_PRIVATE (1<<1)
# define MOD_PROTECTED (1<<2)
# define MOD_STATIC (1<<3)
# define MOD_VIRTUAL (1<<4)
/* Identifiers, etc. */
typedef struct _SymbolTable SymbolTable;
typedef struct _AST AST;
typedef struct _Type Type;
typedef struct _Node {
struct _Node *next,
*tnext;
} Node;
/* Symbol structure */
typedef struct _Symbol {
/* ->tnext is for manipulation of Symbols outside
* Symbol tables, etc. such as temporary lists.
* ->next is used by the symbol table methods.
* NOTE: next and tnext must be the first 2 members of the struct
*/
struct _Symbol *next,
*tnext;
char *name;
int scope;
int flags;
/* Symbol.class is initially IDENTIFIER if it is not resolved to
* a type, variable, function, etc. Upon resolution it will be
* one of TYPE, LITERAL, VARIABLE, METHOD, NAMESPACE
*/
int kind;
struct _Symbol *typename;
Type *type;
int is_lval;
struct _Symbol *namespace; /* What namespace or class owns me */
SymbolTable *table; /* If I'm a namespace/class, this is my symbol table */
struct _Symbol *literal;
int line;
} Symbol;
/* Node for Abstract Syntax Tree */
struct _AST {
/* next and tnext must be the first 2 members of the struct */
struct _AST *next,
*tnext;
struct _AST *up,
*arg1,
*arg2;
/* start_label is 1st statement in construct
* end_label is _after_ last statement so it can
* be used to jump out, break, etc. from loops, switches.
*/
char *start_label,
*end_label;
enum ASTKIND kind; /* General node class (STATEMENT) */
enum ASTTYPE asttype; /* Specific node type (IF|ASSIGN|...)*/
int op; /* Operation */
Type *type; /* Unresolved until type-check pass */
Symbol *typename;
Symbol *sym;
/* Expression generic nodes */
Symbol *targ;
Symbol *vars;
/* Conditional specific nodes
* Reuse above nodes for if_then_else
* arg1 = _then_ branch
* arg2 = _else_ branch
*/
union {
/*
struct _EXPR {
struct _AST *arg1;
struct _AST *arg2;
} Expr;
*/
struct _CLASS {
struct _AST *body;
} Class;
struct _CONDITIONAL {
struct _AST *condition, *end;
} Conditional;
struct _METHOD {
struct _Symbol *params;
struct _AST *body;
} Method;
struct _LOOP {
struct _AST *init;
struct _AST *iteration;
struct _AST *condition;
struct _AST *body;
} Loop;
} Attr;
};
# define HASH_SIZE 109
struct _SymbolTable {
long count;
int scope;
Symbol *table[HASH_SIZE];
};
/* Array stuff */
typedef struct _Rank {
Node *next,
*tnext;
int dim;
} Rank;
struct _Type {
Node *next,
*tnext;
unsigned long flags;
enum TYPES kind; /* class, array, pointer/reference */
int size;
/*
int typeid;
int parentid;
*/
Symbol *sym; /* symbol representing name of type */
Type *type; /* Element or referenced type */
};
typedef struct _Array {
Node *next,
*tnext;
Type *type; /* The type of element */
Rank *rank;
int dim; /* Total dim, can be derived from evaluating rank list */
int **bounds; /* N x 2 dimensional array of bounds where N = dimensions */
} __Array;
/*
* Symbol tables, scope stacks, for handling
* classes, namespaces, etc.
*/
/* This will be some static method, Main from a
* single class in the assembly, if it is executable.
*/
extern Symbol *main_method;
/* The static, global symbol table */
extern Symbol *global_namespace;
extern SymbolTable *global_symbol_table;
/* The current working symbol table */
extern SymbolTable *current_symbol_table;
/*
* The stack of symbols representing the current
* nested scope (namespaces, classes, etc.)
* Namespaces and classes are represented by a Symbol
* and each hold a SymbolTable which holds any nested
* types and members for the particular object.
*/
extern Symbol *namespace_stack;
/* The current working namespace or class.
* current_namespace->table == current_symbol_table
*/
extern Symbol *current_namespace;
extern int scope;
/* Pointers to the builtin type entries in the symbol table */
extern Type *t_object,
*t_void,
*t_string,
*t_bool,
*t_sbyte,
*t_byte,
*t_char,
*t_int32,
*t_uint32,
*t_int64,
*t_uint64,
*t_short,
*t_ushort,
*t_float,
*t_double,
*t_decimal;
void assert(void * p);
void push(Node ** list, Node * p);
void tpush(Node ** list, Node * p);
void tunshift(Node ** list, Node * p);
Node *pop(Node ** list);
Node *tpop(Node ** list);
Symbol *new_symbol(const char * name);
Symbol *new_identifier_symbol(const char * name);
Symbol *new_literal_symbol(const char * name);
Symbol *new_type_symbol(const char * name);
Symbol *mk_namespace_symbol(Symbol *);
Symbol *mk_class_symbol(Symbol *);
Symbol *mk_method_symbol(Symbol *, const char *, const char *);
Symbol *symbol_concat(Symbol *, Symbol *);
Symbol *symbol_join3(Symbol *, Symbol *, Symbol *);
Symbol *symbol_join4(Symbol *, Symbol *, Symbol *, Symbol *);
SymbolTable *new_symbol_table();
void push_sym(Symbol ** list, Symbol * p);
void tpush_sym(Symbol ** list, Symbol * p);
void tunshift_sym(Symbol ** list, Symbol * p);
Symbol *pop_sym(Symbol ** list);
Symbol *tpop_sym(Symbol ** list);
void push_namespace(Symbol * ns);
Symbol *pop_namespace();
void init_symbol_tables();
void init_builtin_types();
Symbol *split(const char *, const char *);
unsigned int hash_str(const char * str);
Symbol *lookup_symbol(const char *);
Symbol *lookup_symbol_in_tab(SymbolTable *, const char *);
Symbol *lookup_symbol_scope(SymbolTable *, const char *, int);
Symbol *lookup_namespace(SymbolTable * tab, const char * name);
Symbol *lookup_class(SymbolTable * tab, const char * name);
Symbol *store_symbol(SymbolTable *, Symbol *);
Symbol *store_identifier(SymbolTable *, Symbol *);
Symbol *store_method(SymbolTable *, const char * name, Type *);
int push_scope();
Symbol *pop_scope();
void discard_scope();
void declare_local(Symbol * id);
/*
* Type related utilities
*/
extern Type **type_table;
extern int type_table_size;
Type *store_type(const char * name, int size);
Type *lookup_type(const char * name);
Type *lookup_type_symbol(Symbol * id);
const char *type_name(Type *);
void coerce_operands(Type ** t1, Type ** t2);
Type *new_array(Symbol * typename, Rank * rank);
Rank *new_rank(int dim);
Symbol *array_signature(Type * t);
/* Type checking and semantic phase */
void build_ast(AST *);
void build_class_decl(AST *);
void build_class_body(AST *);
void build_method_decl(AST *);
void build_field_decl(AST *);
void build_statement_list(AST *);
void build_expr_list(AST *);
void build_expr(AST *);
void build_if(AST *);
void build_conditional(AST *);
void build_method_call(AST *);
void build_new_expr(AST *);
void build_loop(AST *);
void build_return(AST *);
void resolve_identifier(Symbol **);
char *str_dup(const char *);
char *str_cat(const char *, const char *);
void dump_namespace(Symbol *);
void dump_symbol_table(SymbolTable *);
Symbol *check_id_redecl(SymbolTable * table, const char * name);
Symbol *check_id_decl(SymbolTable * table, const char * name);
void unshift_ast(AST ** list, AST * p);
AST *new_ast(enum ASTKIND kind, int type, AST * left, AST * right);
AST *new_statement(int type, AST * left, AST * right);
AST *new_expr(int type, AST * left, AST * right);
AST *new_op_expr(AST * left, int op, AST * right);
AST *new_logical_expr(AST * left, int op, AST * right);
AST *new_if(AST * condition, AST *, AST *);
AST *new_conditional(AST * condition, AST *, AST *);
AST *new_while(AST * condition, AST * block);
AST *new_for(AST * init, AST * condition, AST * increment, AST * block);
extern int primary_block;
extern AST *primary_block_stack[];
void push_primary_block(AST *p);
AST *pop_primary_block();
AST *get_cur_primary_block();
AST *cur_method;
/* Code generation phase */
void gen_ast(AST * ast);
void gen_namespace_decl(AST *);
void gen_class_decl(AST *);
void gen_class_body(AST * ast);
void gen_field_decl(AST * ast);
void gen_constant_decl(AST * ast);
void gen_method_decl(AST * ast);
void gen_block(AST * ast);
void gen_statement(AST * ast);
void gen_var_decl(AST * ast);
void gen_assign(AST * ast);
void gen_expr(AST * ast, Symbol * lval, Type * t);
void gen_method_call(AST *);
void gen_if(AST *);
void gen_while(AST *);
void gen_for(AST *);
void gen_boolean(AST *, const char * true_label, const char * false_label,
int invert);
void emit_op_expr(Symbol * res, Symbol * arg1, char * op, Symbol * arg2);
void emit_unary_expr(Symbol * res, Symbol * arg1, char * op);
char *new_itemp();
char *new_ntemp();
char *new_stemp();
char *new_ptemp();
Symbol *new_temp(Type * t);
void reset_temps();
char *get_label();
char *make_label();
char *op_name(int);
int op_inverse(int);
# define NAME(x) (x->literal == NULL ? x->name : x->literal->name)
# define IS_LVAL(x) (x->is_lval)
# define IS_RVAL(x) (!x->is_lval)
# define SWITCH_OR_LOOP() (primary_block > 0 ? 1 : 0)
# define eval_expr(x) ((x->asttype == ASTT_LITERAL || x->asttype == ASTT_IDENTIFIER) ? (x->targ = x->sym, 1) : 0)
extern long line;
#endif /* PARROT_LANGUAGES_COLA_H_GUARD */
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4:
*/
syntax highlighted by Code2HTML, v. 0.9.1