150 likes | 262 Views
Project Metainformation. Your program should: Parse input and construct an AST Print the normal representation of the AST followed by a line of asterisks (you decide how many) Evaluate the AST If you complete parts 1 and 2, successfully, you will receive no less than 75/100 points.
E N D
Project Metainformation • Your program should: • Parse input and construct an AST • Print the normal representation of the AST followed by a line of asterisks (you decide how many) • Evaluate the AST • If you complete parts 1 and 2, successfully, you will receive no less than 75/100 points. • If you complete 1 and 2, and can eval this input correctly, you will receive no less than 85/100 points: print(1); print(-2); print(-(-(3))); • The due date for this part of the project is extended until Tuesday 28 October.
What will we hand in? • tar –zcvf garnet.tgz *.h *.c *.l *.y Sourcesthen submit garnet.tgz • I will use my own Makefile. You don’t need to give me yours. • Make sure your Sources file has the right stuff in it. • No .c files? Make sure to find out how to write a C++ program! • Don’t have tar on your pc? How the heck are you compiling using g++ but you don’t have tar????
Late Policy • Despite what misinformation Wilson may have spread last Thursday, the late policy is the following: • 1 day late: maximum grade 80% • 2 days late: maximum grade 50% • 3 days late: maximum grade 0% • Better to get something mostly working and turn it in than be a perfectionist with zero credit.
Things to Know From Wilson’s Suggestions • The GarnetPtr class is a discriminated union of all types of things that can appear in an object slot. It includes at least the following: GarnetObject* string* int double GarnetPtr (*)(GarnetPtr, GarnetPtr) vector<GarnetPtr>* • The next to the last element is a function pointer to a function that can be used as a primitive Garnet method implementation.
Garnet Classes vs. C++ Classes • The Garnet class hierarchy does not exist as a C++ class hierarchy. • Although you may have a variety of classes representing the elements of your AST, there is only one class representing Garnet objects, namely GarnetObject. • Every Garnet object, whether it is an Integer, String, or even a Class is represented by a GarnetObject. • Each GarnetObject is a pair containing a myclass element (referring to the class of this object) and a vector<GarnetPtr> * containing the slot values for that particular object.
myclass vs. superclass • An Integer object in Garnet (such as the number 1) has a myclassGarnetPtr that refers to the class Integer, that is, the class of which this particular integer is an instance. • The Integer class object, however, has a myclass that refers to the class Class, because the Integer class is a class. The Integer class object also contains a superclassslot. This is because each class (except Object) has a superclass from which it is derived.(Refer again to the diagram from last Thursday.)
How Can We Construct that Class Hierarchy? • Strategy: Represent each class with a GarnetPtr containing a GarnetObject* • Plan: • Statically allocate the GarnetPtrs for all built-in classes.In Garnet.h: extern GarnetPtr Object; extern GarnetPtr Class; ... extern GarnetPtr NilClass;In Garnet.c: GarnetPtr Object; GarnetPtr Class; ... GarnetPtr NilClass;
Constructing the Class Hierarchy 2. In an initialization method (probably a friend of both GarnetObject and GarnetPtr), assign proper contents to the already allocated class GarnetPtrs. class GarnetPtr { ...friend void do_init(); ...};class GarnetObject{ ...friend void do_init(); ...};voiddo_init(){ ... Class.d = d_gptr; // set discriminant correctly Class.u.gptr = new GarnetObject(); // We have to give this a value here Class.u.gptr->myclass = Class; // to be able to assign it. Class.u.slotsvec = cls_slotsvecptr; // I assume slotsvecptr has already been initialized // to have the right slot values for the Class object ... Object.d = d_gptr; // The rest of the classes can be made more reasonably Object.u.gptr = new GarnetObject(Class, obj_slotsvecptr); }
How Do I Create Slot Values for Class? vector<GarnetPtr> *c_slotnames = new vector<GarnetPtr>; c_slotnames->push_back(make_string("superclass")); c_slotnames->push_back(make_string("method_names")); c_slotnames->push_back(make_string("method_objects")); c_slotnames->push_back(make_string("slots")); c_slotnames->push_back(make_string("class_name")); vector<GarnetPtr> *c_mnames = new vector<GarnetPtr>; vector<GarnetPtr> *c_mobjs = new vector<GarnetPtr>; c_mnames->push_back(make_string("superclass")); c_mobjs->push_back(make_method(superclass)); c_mnames->push_back(make_string("to_s")); c_mobjs->push_back(make_method(class_to_s)); etc.
Constructing the Class Hierarchy • Hint: Implement Class and String first and then create methods to print GarnetPtr and GarnetObject values. • I have print and briefprint methods.The print method prints the class name of the object, followed by its slot names and a briefprint of their values. The briefprint method prints either the string value or the class name followed by the pointer address of the object (or its name if it’s a class). For example:print for Class:Instance of: Class superclass: <Class:Object> methodnames: superclass to_s methodobjects: <Method:106596> <Method:106532> slots: superclass method_names method_objects slots class_name class_name: Classbriefprint for Class:<Class:Class>
More on Built-in Classes • Here’s how the class Integer printed when I had just developed a method for – for it:Instance of: Class superclass: <Class:Object> method_names: to_s – method_objects: <Method:108808> <Method:109664> slots: $rep class_name: Integer • I named the slot for the representation of the integer value $rep to make sure users cannot access that field. ($ cannot appear in Garnet identifier names.)
Convenience Functions • I created a number of convenience functions to make life easier for myself: • GarnetPtr getslot(GarnetPtr objptr, int n); • GarnetPtr getsuper(GarnetPtr classptr); • int prim_lookup(string meth_name, GarnetPtr classptr);// returns the index of the named method or// -1 if the method is not found in this class • MethodPtr lookup_method(string meth_name, GarnetPtr objptr)// MethodPtr is declared as follows:// GarnetPtr (*MethodPtr) (GarnetPtr, GarnetPtr);
Wilson’s lookup_method(Your mileage may vary) MethodPtr lookup_method(string methodname, GarnetPtr class_obj) { MethodPtr this_method = 0; while (this_method == 0) { int i = prim_lookup_method(methodname, class_obj); if (i >= 0) { this_method = (*((*getslot(class_obj,CLASS_METHOD_OBJS_INX).vp())[i]).gp()->slotsvec)[0].fp(); } else { class_obj = getslot(class_obj,0); if (class_obj == NilObject) { // superclass of Object was initialized to global NilObject cerr << "Can't find method " << methodname << endl; abort(); } } } return this_method; }
How to Make a Variable Map #include <map> #include <iostream> using namespace std; int main(int argc, char **argv) { map<const char *,int> varmap; varmap["a"] = 1; varmap["b"] = 3; cout << varmap["a"] << endl; cout << varmap["b"] << endl; varmap["b"] = 4; cout << varmap["b"] << endl; } considermap<const char *, GarnetPtr> GlobalFrame;
Next Project Increment • You’ll modify your existing program to generate code (with a generate method in each AST class). • If you are reading input file fname.g, then you will generate C++ code in fname.c and will exec g++ -o fnamefname.c