/* 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);