mirror of
https://github.com/vishapoberon/compiler.git
synced 2026-04-07 04:32:24 +00:00
ported ulmLoader, ulmNetIO, ulmPersistentDisciplines, ulmPersistentObjects, ulmScales
fixed ulmConstStrings
Former-commit-id: e76b8bf27c
This commit is contained in:
parent
4e45337b83
commit
e989e42d42
7 changed files with 2680 additions and 1 deletions
443
src/lib/ulm/ulmScales.Mod
Normal file
443
src/lib/ulm/ulmScales.Mod
Normal file
|
|
@ -0,0 +1,443 @@
|
|||
(* Ulm's Oberon Library
|
||||
Copyright (C) 1989-1994 by University of Ulm, SAI, D-89069 Ulm, Germany
|
||||
----------------------------------------------------------------------------
|
||||
Ulm's Oberon Library is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either version
|
||||
2 of the License, or (at your option) any later version.
|
||||
|
||||
Ulm's Oberon Library is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
----------------------------------------------------------------------------
|
||||
E-mail contact: oberon@mathematik.uni-ulm.de
|
||||
----------------------------------------------------------------------------
|
||||
$Id: Scales.om,v 1.3 2004/09/03 09:31:53 borchert Exp $
|
||||
----------------------------------------------------------------------------
|
||||
$Log: Scales.om,v $
|
||||
Revision 1.3 2004/09/03 09:31:53 borchert
|
||||
bug fixes: Services.Init added in CreateOperand
|
||||
Scales.Measure changed to Measure
|
||||
|
||||
Revision 1.2 1995/01/16 21:40:39 borchert
|
||||
- assertions of Assertions converted into real assertions
|
||||
- fixes due to changed if of PersistentObjects
|
||||
|
||||
Revision 1.1 1994/02/22 20:10:03 borchert
|
||||
Initial revision
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
AFB 12/91
|
||||
----------------------------------------------------------------------------
|
||||
*)
|
||||
|
||||
MODULE ulmScales;
|
||||
|
||||
IMPORT Disciplines := ulmDisciplines, Events := ulmEvents, Objects := ulmObjects, Operations := ulmOperations, PersistentObjects := ulmPersistentObjects,
|
||||
RelatedEvents := ulmRelatedEvents, Services := ulmServices;
|
||||
|
||||
TYPE
|
||||
Scale* = POINTER TO ScaleRec;
|
||||
Family* = POINTER TO FamilyRec;
|
||||
FamilyRec* =
|
||||
RECORD
|
||||
(Disciplines.ObjectRec)
|
||||
(* private components *)
|
||||
reference: Scale;
|
||||
END;
|
||||
|
||||
TYPE
|
||||
Unit* = POINTER TO UnitRec;
|
||||
UnitList = POINTER TO UnitListRec;
|
||||
UnitListRec =
|
||||
RECORD
|
||||
unit: Unit;
|
||||
next: UnitList;
|
||||
END;
|
||||
Interface = POINTER TO InterfaceRec;
|
||||
ScaleRec* =
|
||||
RECORD
|
||||
(Disciplines.ObjectRec)
|
||||
(* private components *)
|
||||
if: Interface;
|
||||
family: Family;
|
||||
head, tail: UnitList;
|
||||
nextUnit: UnitList;
|
||||
END;
|
||||
|
||||
CONST
|
||||
unitNameLength* = 32;
|
||||
TYPE
|
||||
UnitName* = ARRAY unitNameLength OF CHAR;
|
||||
UnitRec* = RECORD
|
||||
(Disciplines.ObjectRec)
|
||||
name: UnitName;
|
||||
scale: Scale;
|
||||
END;
|
||||
|
||||
CONST
|
||||
undefined = 0; absolute* = 1; relative* = 2;
|
||||
TYPE
|
||||
Measure* = POINTER TO MeasureRec;
|
||||
MeasureRec* =
|
||||
RECORD
|
||||
(Operations.OperandRec)
|
||||
scale: Scale;
|
||||
type: SHORTINT; (* absolute or relative? *)
|
||||
END;
|
||||
VAR
|
||||
measureType: Services.Type;
|
||||
|
||||
TYPE
|
||||
Value* = LONGINT;
|
||||
|
||||
CONST
|
||||
add* = Operations.add; sub* = Operations.sub;
|
||||
TYPE
|
||||
Operation* = SHORTINT; (* add or sub *)
|
||||
TYPE
|
||||
CreateProc* = PROCEDURE (scale: Scale; VAR measure: Measure; abs: BOOLEAN);
|
||||
GetValueProc* = PROCEDURE (measure: Measure; unit: Unit; VAR value: Value);
|
||||
SetValueProc* = PROCEDURE (measure: Measure; unit: Unit; value: Value);
|
||||
AssignProc* = PROCEDURE (target: Measure; source: Measure);
|
||||
OperatorProc* = PROCEDURE (op: Operation; op1, op2, result: Measure);
|
||||
CompareProc* = PROCEDURE (op1, op2: Measure) : INTEGER;
|
||||
ConvertProc* = PROCEDURE (from, to: Measure);
|
||||
|
||||
InterfaceRec* =
|
||||
RECORD
|
||||
(Objects.ObjectRec)
|
||||
create*: CreateProc;
|
||||
getvalue*: GetValueProc;
|
||||
setvalue*: SetValueProc;
|
||||
assign*: AssignProc;
|
||||
op*: OperatorProc;
|
||||
compare*: CompareProc;
|
||||
(* the conversion routines are only to be provided
|
||||
if the scaling system belongs to a family
|
||||
*)
|
||||
scaleToReference*: ConvertProc;
|
||||
referenceToScale*: ConvertProc;
|
||||
END;
|
||||
|
||||
VAR
|
||||
invalidOperation*: Events.EventType;
|
||||
(* operation cannot be performed for the given combination
|
||||
of types (absolute or relative)
|
||||
*)
|
||||
incompatibleScales*: Events.EventType;
|
||||
(* the scales of the operands do not belong to the same family *)
|
||||
badCombination*: Events.EventType;
|
||||
(* SetValue or GetValue:
|
||||
given measure and unit do not belong to the same scaling system
|
||||
*)
|
||||
|
||||
(* our interface to Operations *)
|
||||
opif: Operations.Interface;
|
||||
opcaps: Operations.CapabilitySet;
|
||||
|
||||
(* ======= private procedures ===================================== *)
|
||||
|
||||
PROCEDURE DummyConversion(from, to: Measure);
|
||||
BEGIN
|
||||
from.scale.if.assign(to, from);
|
||||
END DummyConversion;
|
||||
|
||||
(* ======== exported procedures ==================================== *)
|
||||
|
||||
PROCEDURE InitFamily*(family: Family; reference: Scale);
|
||||
BEGIN
|
||||
family.reference := reference;
|
||||
(* the reference scale becomes now a member of the family *)
|
||||
reference.family := family;
|
||||
reference.if.scaleToReference := DummyConversion;
|
||||
reference.if.referenceToScale := DummyConversion;
|
||||
END InitFamily;
|
||||
|
||||
PROCEDURE Init*(scale: Scale; family: Family; if: Interface);
|
||||
(* reference scales are to be initialized with family = NIL *)
|
||||
BEGIN
|
||||
scale.if := if;
|
||||
scale.family := family;
|
||||
scale.head := NIL; scale.tail := NIL;
|
||||
scale.nextUnit := NIL;
|
||||
END Init;
|
||||
|
||||
PROCEDURE InitUnit*(scale: Scale; unit: Unit; name: UnitName);
|
||||
VAR
|
||||
listp: UnitList;
|
||||
BEGIN
|
||||
unit.name := name;
|
||||
unit.scale := scale;
|
||||
NEW(listp); listp.unit := unit; listp.next := NIL;
|
||||
IF scale.head # NIL THEN
|
||||
scale.tail.next := listp;
|
||||
ELSE
|
||||
scale.head := listp;
|
||||
END;
|
||||
scale.tail := listp;
|
||||
END InitUnit;
|
||||
|
||||
PROCEDURE CreateMeasure*(scale: Scale; VAR measure: Measure; type: SHORTINT);
|
||||
BEGIN
|
||||
scale.if.create(scale, measure, type = absolute);
|
||||
Operations.Init(measure, opif, opcaps);
|
||||
measure.scale := scale;
|
||||
measure.type := type;
|
||||
END CreateMeasure;
|
||||
|
||||
PROCEDURE CreateAbsMeasure*(scale: Scale; VAR measure: Measure);
|
||||
(* init measure to the origin of the given system *)
|
||||
BEGIN
|
||||
CreateMeasure(scale, measure, absolute);
|
||||
END CreateAbsMeasure;
|
||||
|
||||
PROCEDURE CreateRelMeasure*(scale: Scale; VAR measure: Measure);
|
||||
(* init relative measure to 0 *)
|
||||
BEGIN
|
||||
CreateMeasure(scale, measure, relative);
|
||||
END CreateRelMeasure;
|
||||
|
||||
PROCEDURE ConvertMeasure*(scale: Scale; VAR measure: Measure);
|
||||
(* convert measure to the given scale which must belong
|
||||
to the same family as the original scale of measure
|
||||
*)
|
||||
VAR
|
||||
newMeasure: Measure;
|
||||
refMeasure: Measure;
|
||||
reference: Scale;
|
||||
BEGIN
|
||||
IF scale = measure.scale THEN
|
||||
(* trivial case -- nothing is to be done *)
|
||||
RETURN
|
||||
END;
|
||||
(* check that both scales belong to the same family *)
|
||||
ASSERT((scale.family # NIL) & (scale.family = measure.scale.family));
|
||||
CreateMeasure(scale, newMeasure, measure.type);
|
||||
reference := scale.family.reference;
|
||||
CreateMeasure(reference, refMeasure, measure.type);
|
||||
measure.scale.if.scaleToReference(measure, refMeasure);
|
||||
scale.if.referenceToScale(refMeasure, newMeasure);
|
||||
measure := newMeasure;
|
||||
END ConvertMeasure;
|
||||
|
||||
PROCEDURE GetReference*(family: Family; VAR reference: Scale);
|
||||
BEGIN
|
||||
reference := family.reference;
|
||||
END GetReference;
|
||||
|
||||
PROCEDURE GetFamily*(scale: Scale; VAR family: Family);
|
||||
BEGIN
|
||||
family := scale.family;
|
||||
END GetFamily;
|
||||
|
||||
PROCEDURE GetScaleOfUnit*(unit: Unit; VAR scale: Scale);
|
||||
BEGIN
|
||||
scale := unit.scale;
|
||||
END GetScaleOfUnit;
|
||||
|
||||
PROCEDURE GetScale*(measure: Measure; VAR scale: Scale);
|
||||
BEGIN
|
||||
scale := measure.scale;
|
||||
END GetScale;
|
||||
|
||||
PROCEDURE TraverseUnits*(scale: Scale);
|
||||
BEGIN
|
||||
scale.nextUnit := scale.head;
|
||||
END TraverseUnits;
|
||||
|
||||
PROCEDURE NextUnit*(scale: Scale; VAR unit: Unit) : BOOLEAN;
|
||||
BEGIN
|
||||
IF scale.nextUnit # NIL THEN
|
||||
unit := scale.nextUnit.unit;
|
||||
scale.nextUnit := scale.nextUnit.next;
|
||||
RETURN TRUE
|
||||
ELSE
|
||||
RETURN FALSE
|
||||
END;
|
||||
END NextUnit;
|
||||
|
||||
PROCEDURE GetName*(unit: Unit; VAR name: UnitName);
|
||||
BEGIN
|
||||
name := unit.name;
|
||||
END GetName;
|
||||
|
||||
PROCEDURE GetValue*(measure: Measure; unit: Unit; VAR value: Value);
|
||||
VAR
|
||||
scale: Scale;
|
||||
BEGIN
|
||||
scale := measure.scale;
|
||||
ASSERT(unit.scale = scale);
|
||||
scale.if.getvalue(measure, unit, value);
|
||||
END GetValue;
|
||||
|
||||
PROCEDURE SetValue*(measure: Measure; unit: Unit; value: Value);
|
||||
VAR
|
||||
scale: Scale;
|
||||
BEGIN
|
||||
scale := measure.scale;
|
||||
ASSERT(unit.scale = scale);
|
||||
scale.if.setvalue(measure, unit, value);
|
||||
END SetValue;
|
||||
|
||||
PROCEDURE IsAbsolute*(measure: Measure) : BOOLEAN;
|
||||
BEGIN
|
||||
RETURN measure.type = absolute
|
||||
END IsAbsolute;
|
||||
|
||||
PROCEDURE IsRelative*(measure: Measure) : BOOLEAN;
|
||||
BEGIN
|
||||
RETURN measure.type = relative
|
||||
END IsRelative;
|
||||
|
||||
PROCEDURE MeasureType*(measure: Measure) : SHORTINT;
|
||||
BEGIN
|
||||
RETURN measure.type
|
||||
END MeasureType;
|
||||
|
||||
(* ======== interface procedures for Operations ================= *)
|
||||
|
||||
PROCEDURE CreateOperand(VAR op: Operations.Operand);
|
||||
(* at this time we don't know anything about the
|
||||
associated scale -- so we've have to delay this decision
|
||||
*)
|
||||
VAR
|
||||
measure: Measure;
|
||||
BEGIN
|
||||
NEW(measure);
|
||||
measure.type := undefined;
|
||||
measure.scale := NIL;
|
||||
Services.Init(measure, measureType);
|
||||
op := measure;
|
||||
Operations.Init(op, opif, {Operations.add..Operations.cmp});
|
||||
END CreateOperand;
|
||||
|
||||
PROCEDURE Assign(VAR target: Operations.Operand; source: Operations.Operand);
|
||||
BEGIN
|
||||
WITH source: Measure DO WITH target: Measure DO
|
||||
(* target is already initialized but possibly to a dummy operand
|
||||
by CreateOperand
|
||||
*)
|
||||
IF target.type = undefined THEN
|
||||
(* init target with the scale of source *)
|
||||
CreateMeasure(source.scale, target, source.type);
|
||||
END;
|
||||
IF target.scale # source.scale THEN
|
||||
(* adapt scale type from source --
|
||||
this could lead to a type guard failure if
|
||||
target is not of the appropiate type
|
||||
*)
|
||||
CreateMeasure(source.scale, target, source.type);
|
||||
END;
|
||||
IF target.type # source.type THEN
|
||||
(* adapt measure type from source *)
|
||||
CreateMeasure(target.scale, target, source.type);
|
||||
END;
|
||||
source.scale.if.assign(target, source);
|
||||
END; END;
|
||||
END Assign;
|
||||
|
||||
PROCEDURE CheckCompatibility(op1, op2: Operations.Operand;
|
||||
VAR m1, m2: Measure);
|
||||
(* is needed by Op and Compare:
|
||||
both operands are checked to be members of the same family;
|
||||
if they have different scales of the same family a
|
||||
conversion is done;
|
||||
*)
|
||||
VAR
|
||||
scale1, scale2: Scale;
|
||||
BEGIN
|
||||
WITH op1: Measure DO WITH op2: Measure DO
|
||||
scale1 := op1.scale; scale2 := op2.scale;
|
||||
IF scale1 # scale2 THEN
|
||||
ASSERT((scale1.family # NIL) & (scale1.family = scale2.family));
|
||||
(* convert both operands to the reference scale *)
|
||||
CreateMeasure(scale1.family.reference, m1, op1.type);
|
||||
scale1.if.scaleToReference(op1, m1);
|
||||
CreateMeasure(scale2.family.reference, m2, op2.type);
|
||||
scale2.if.scaleToReference(op2, m2);
|
||||
ELSE
|
||||
m1 := op1;
|
||||
m2 := op2;
|
||||
END;
|
||||
END; END;
|
||||
END CheckCompatibility;
|
||||
|
||||
PROCEDURE Op(op: Operations.Operation; op1, op2: Operations.Operand;
|
||||
VAR result: Operations.Operand);
|
||||
VAR
|
||||
restype: SHORTINT; (* type of result -- set by CheckTypes *)
|
||||
m1, m2: Measure;
|
||||
|
||||
PROCEDURE CheckTypes(VAR restype: SHORTINT);
|
||||
(* check operands for correct typing;
|
||||
sets restype to the correct result type;
|
||||
*)
|
||||
VAR ok: BOOLEAN;
|
||||
BEGIN
|
||||
WITH op1: Measure DO WITH op2: Measure DO
|
||||
CASE op OF
|
||||
| Operations.add: (* only abs + abs is invalid *)
|
||||
ok := (op1.type = relative) OR
|
||||
(op2.type = relative);
|
||||
IF op1.type = op2.type THEN
|
||||
(* both are relative *)
|
||||
restype := relative;
|
||||
ELSE
|
||||
(* exactly one absolute type is involved *)
|
||||
restype := absolute;
|
||||
END;
|
||||
| Operations.sub: (* only rel - abs is invalid *)
|
||||
ok := op1.type <= op2.type;
|
||||
IF op1.type # op2.type THEN
|
||||
(* abs - rel *)
|
||||
restype := absolute;
|
||||
ELSE
|
||||
(* abs - abs or rel - rel *)
|
||||
restype := relative;
|
||||
END;
|
||||
END;
|
||||
ASSERT(ok); (* invalid operation *)
|
||||
END; END;
|
||||
END CheckTypes;
|
||||
|
||||
BEGIN (* Op *)
|
||||
(* result is already of type Measure; this is guaranteed by Operations *)
|
||||
WITH result: Measure DO
|
||||
CheckTypes(restype);
|
||||
CheckCompatibility(op1, op2, m1, m2);
|
||||
CreateMeasure(m1.scale, result, restype);
|
||||
m1.scale.if.op(op, m1, m2, result);
|
||||
END;
|
||||
END Op;
|
||||
|
||||
PROCEDURE Compare(op1, op2: Operations.Operand) : INTEGER;
|
||||
VAR
|
||||
m1, m2: Measure;
|
||||
BEGIN
|
||||
CheckCompatibility(op1, op2, m1, m2);
|
||||
ASSERT(m1.type = m2.type);
|
||||
CheckCompatibility(op1, op2, m1, m2);
|
||||
RETURN m1.scale.if.compare(m1, m2)
|
||||
END Compare;
|
||||
|
||||
PROCEDURE InitInterface;
|
||||
BEGIN
|
||||
NEW(opif);
|
||||
opif.create := CreateOperand;
|
||||
opif.assign := Assign;
|
||||
opif.op := Op;
|
||||
opif.compare := Compare;
|
||||
opcaps := {Operations.add, Operations.sub, Operations.cmp};
|
||||
END InitInterface;
|
||||
|
||||
BEGIN
|
||||
InitInterface;
|
||||
PersistentObjects.RegisterType(measureType,
|
||||
"Scales.Measure", "Operations.Operand", NIL);
|
||||
END ulmScales.
|
||||
Loading…
Add table
Add a link
Reference in a new issue