/* Sun-$Revision: 23.6 $ */
/* Copyright 1992-9 Sun Microsystems, Inc. and Stanford University.
See the LICENSE file for license information. */
# pragma interface
// Exprs represent parsed Self objects that haven't been turned into real
// (Self-level) objects yet.
struct SlotList;
struct Slot;
struct Object;
struct ArgSlot;
struct ArgSlotList;
struct Expr: ParseNode {
char* source_file;
fint source_line;
fint source_column;
char* source_start;
fint source_length;
Parser* parser; // for error messages
char* source_end() { return source_start + source_length; }
Expr(Parser* p) {
source_file = source_start = "";
source_line = source_column = source_length = 0;
parser = p;}
Expr(char* start, char* end, char* file, fint line, fint col, Parser* p) {
source_start = start;
source_length = end - start;
source_file = file;
source_line = line;
source_column = col;
parser = p;
}
virtual bool IsSend() { return false; }
virtual bool IsBinary() { return false; }
virtual bool IsKeyword() { return false; }
virtual bool IsReturn() { return false; }
virtual bool IsSelf() { return false; }
virtual bool IsObject() { return false; }
virtual bool IsMethod() { return false; }
virtual bool isConstant() { return false; }
virtual oop get_label() {
ErrorMessage("branch destination must be a constant");
return badOop; }
virtual bool ContainsMethod() { return false; }
virtual Expr* AddArg(ArgSlot* arg, Parser* parser);
virtual Expr* AddArgs(ArgSlotList* args, Parser* parser);
virtual oop Eval(bool printing = false, bool inSlot = false);
void ErrorMessage(char* msg);
fint position_in_method(Object* parent);
};
struct ExprListElement: ListElement {
ExprListElement(Expr* d, ExprListElement* n = 0) : ListElement(d, n) {}
Expr* Data() { return (Expr*) ListElement::Data(); }
ExprListElement* Next() { return (ExprListElement*) ListElement::Next(); }
};
struct ExprList: List {
ExprList() : List() {}
ExprList(Expr* e) : List(e) {}
ExprListElement* Head() { return (ExprListElement*) List::Head(); }
ExprListElement* Tail() { return (ExprListElement*) List::Tail(); }
ExprList* Append(Expr* e) { return (ExprList*) List::Append(e); }
};
struct Pop: Expr {
Pop(char* start, char* end, char* file, fint line, fint col, Parser* p)
: Expr(start, end, file, line, col, p) {}
bool GenByteCodes(AbstractByteCode* b, Object* parent, bool isExpr = true);
void Print();
};
struct Self: Expr {
Self(char* start, char* end, char* file, fint line, fint col, Parser* p)
: Expr(start, end, file, line, col, p) {}
bool IsSelf() { return true; }
bool GenByteCodes(AbstractByteCode* b, Object* parent, bool isExpr = true);
void Print();
};
struct Constant: Expr {
oop value;
Constant(oop v, Parser* p) : Expr(p) { value = v; }
Constant(oop val, char* start, char* end, char* file, fint line, fint col, Parser* p)
: Expr(start, end, file, line, col, p) {
value = val;
}
bool isConstant() { return true; }
oop get_label() { return value; }
bool GenByteCodes(AbstractByteCode* b, Object* parent, bool isExpr = true);
oop Eval(bool printing = false, bool inSlot = false) {
return printing ? Expr::Eval(printing, inSlot) : value; }
void oops_do(oopsDoFn f) { (*f)(&value); }
};
struct Integer: Constant {
Integer(int32 v, Parser* p) : Constant(as_smiOop(v), p) {}
Integer(int32 v, char* start, char* end, char* file, fint line, fint col, Parser* p)
: Constant(as_smiOop(v), start, end, file, line, col, p) {}
void Print();
};
struct Float: Constant {
Float(float v, Parser* p) : Constant(as_floatOop(v), p) {}
Float(float v, char* start, char* end, char* file, fint line, fint col, Parser* p)
: Constant(as_floatOop(v), start, end, file, line, col, p) {}
void Print();
};
struct StringLiteral: Constant {
StringLiteral(String* v, Parser* p)
: Constant(new_string(v->AsCharP(), v->len), p) {}
StringLiteral(String* v, char* start, char* end, char* file, fint line,
fint col, Parser* p)
: Constant(new_string(v->AsCharP(), v->len), start, end, file, line, col, p){}
void Print();
};
struct Object: Constant {
SlotList* slots;
ExprList* body;
char* annotation;
// excluded the slots and the parentheses of the object.
char* source_body_start;
fint source_body_length;
fint source_body_line;
fint source_body_column;
bool isDeferred; // true if this is a block.
Object(SlotList* slots,
ExprList* body,
bool isDeferred,
char* source_file,
fint source_line,
fint source_column,
char* source_start,
fint source_length,
fint source_body_line,
fint source_body_col,
char* source_body_start,
fint source_body_length,
Parser* p);
bool IsObject() { return true; }
bool IsMethod() { return !isDeferred && body->Length() != 0; }
bool ContainsMethod();
Expr* AddArg(ArgSlot* arg, Parser* parser);
Expr* AddArgs(ArgSlotList* args, Parser* parser);
bool GenBody(Object* parent);
bool GenByteCodes(AbstractByteCode* b, Object* parent, bool isExpr = true);
// check NLRSupport::have_NLR_through_C() after calling this!
void addCommentAnnotations(Scanner* scanner);
oop Eval(bool printing = false, bool inSlot = false) {
return printing || GenBody(0)
? oop(Constant::Eval(printing, inSlot))
: oop(badOop);
}
void oops_do(oopsDoFn f);
void Print();
};
inline fint Expr::position_in_method(Object* parent) {
return parent != NULL
? source_start - parent->source_body_start
: 0;
}
struct Return: Expr {
Expr* result;
Return(Expr* r, char* start, char* end, char* file, fint line, fint col,
Parser* p)
: Expr(start, end, file, line, col, p) { result = r; }
bool IsReturn() { return true; }
bool GenByteCodes(AbstractByteCode* b, Object* parent, bool isExpr = true);
void oops_do(oopsDoFn f) { Expr::oops_do(f); result->oops_do(f); }
void Print();
};
// return anno + separtator + comment_keyword + comment.
char* extend_annotation_with_comment(char* anno, Token* comment);
// return anno + separator + string.
char* extend_annotation_with_string(char* anno, Token* string);