({version=0.0}) ( ) () () package std { package compiler { class progloc { graam.internal.pointer loc; } class reference { graam.internal.pointer loc; } class datatype { graam.internal.bits(32) id; graam.internal.bits(32) total_bits; graam.internal.bits(32) significant_bits; } class expression { graam.internal.pointer text; graam.internal.pointer val; graam.internal.bits(32) type_id; graam.internal.bits(1) reference; } promote graam.internal.notifypack notifypack; promote graam.internal.icodepack icodepack; } metaclass enum { //++ FILL THIS IN!!! } metaclass number { visible to any: typedef graam.internal.enum(none,min,max,expression,native) nullreptype; graam.internal.bits(1) signed; graam.internal.bits(8) digits; compiler.expression min; compiler.expression max; graam.internal.bits(1) float; graam.internal.bits(8) scale; nullreptype nullrep:=none; compiler.expression nullvalue:=0; // Creates class, returns datatype compiler.datatype type (in graam.internal.bits(1) signed:=1, in graam.internal.bits(8) bits, in graam.internal.bits(8) significant_bits:=bits, in graam.internal.bits(8) digits, in graam.internal.bits(bits) min, in graam.internal.bits(bits) max, in graam.internal.bits(1) float:=0, in graam.internal.bits(8) scale:=0, in nullreptype nullrep:=none; in compiler.expression nullvalue:=0) { method parse_parameter( /*++WHAT GOES HERE???*/ ) { // Called at compile time to evaluate actual parameter expressions and // fill in the values for the formal expressions. This method gets called // only when the parser gets confused about the syntax of an actual // parameter expression. //++Interpret a parameter expression (i.e. "unsigned" or "scale:=float") //++and fill in the parameter info (signed, bits, min, etc.) } // interpret parameters to 'type' to fill in datatype info. datatype.total_bits := bits; datatype.significant_bits := significant_bits; number.signed := signed; number.digits := digits; number.min := min; number.max:= max; number.float := float; number.scale := scale; number.nullrep := nullrep; if (number.nullrep = expression) { number.nullvalue := nullvalue.value; } // build the data type itself and return it. result := graam.internal.bits(total_bits); } method check_types(in number.expression left, in number.expression right, in out number.expression result) () icode { // Make sure left.type_id = right.type_id l_t: eval left.type_id; r_t: eval right.type_id; compare l_t, r_t; jump_eq operands_ok; error; //++ type mismatch between operands FIGURE OUT HOW TO ORGANIZE ERROR MESSAGES operands_ok: null; // Set result.type_id if necessary. res_t: eval "result.type_id"; compare res_t, 0; // no type assigned yet jump_ne result_has_type; assign res_t, l_t; jump done; result_has_type: null; // result.type.id already set. Make sure it's the same check_res: compare res_t, l_t; jump_eq done; error; //++ type mismatch on assignment FIGURE OUT HOW TO ORGANIZE ERROR MESSAGES done: null; } } typedef number(bits:=8) int8; typedef number(bits:=16) int16; typedef number(bits:=32) int32; typedef number(bits:=64) int64; typedef number(unsigned, bits:=8) uint8; typedef number(unsigned, bits:=16) uint16; typedef number(unsigned, bits:=32) uint32; typedef number(unsigned, bits:=64) uint64; typedef number(bits:=64, scale:=float, null:=native) float64; typedef number(bits:=80, scale:=float, null:=native) float80; typedef number(unsigned, bits:=1) pos_bool_type; typedef number(signed, bits:=1) neg_bool_type; typedef enum(false:=pos_bool_type(0), true:=1) pos_bool; typedef enum(false:=neg_bool_type(0), true:=-1) neg_bool; alias pos_bool boolean; typedef number(unsigned, bits:=8) ascii; typedef number(unsigned, bits:=16) unicode; preop number ~ (in number left) icode { a: neg left; assign result, a; } assignop := (in out number left, in number right) ({split=left.type.class}) { number.check_types(left.expression, right.expression, result.expression); icode { assign left, right; } } addop number + (in number left, in number right) ({split=left.type.class}) { number.check_types(left.expression, right.expression, result.expression); icode { a: add left, right; assign result, a; } } addop number - (in number left, in number right) ({split=left.type.class}) { number.check_types(left.expression, right.expression, result.expression); icode { a: sub left, right; assign result, a; } } mulop number * (in number left, in number right) ({split=left.type.class}) { number.check_types(left.expression, right.expression, result.expression); icode { a: mul left, right; assign result, a; } } mulop number / (in number left, in number right) ({split=left.type.class}) { number.check_types(left.expression, right.expression, result.expression); icode { a: div left, right; assign result, a; } } mulop number % (in number left, in number right) ({split=left.type.class}) { number.check_types(left.expression, right.expression, result.expression); icode { a: mod left, right; assign result, a; } } assignop -- (in out number left) { left := left - left.type.epsilon; } assignop ++ (in out number left) { left := left + left.type.epsilon; } assignop += (in out number left, in number right) { left := left + right; } assignop -= (in out number left, in number right) { left := left - right; } assignop *= (in out number left, in number right) { left := left * right; } assignop /= (in out number left, in number right) { left := left / right; } assignop %= (in out number left, in number right) { left := left % right; } } ()