--* From postmaster%watson.vnet.ibm.com@yktvmv.watson.ibm.com  Fri Jun 10 06:26:03 1994
--* Received: from yktvmv-ob.watson.ibm.com by asharp.watson.ibm.com (AIX 3.2/UCB 5.64/930311)
--*           id AA22144; Fri, 10 Jun 1994 06:26:03 -0400
--* Received: from watson.vnet.ibm.com by yktvmv.watson.ibm.com (IBM VM SMTP V2R3)
--*    with BSMTP id 8737; Fri, 10 Jun 94 06:26:04 EDT
--* Received: from YKTVMV by watson.vnet.ibm.com with "VAGENT.V1.0"
--*           id <A.BRONSTEI.NOTE.YKTVMV.1165.Jun.10.06:26:04.-0400>
--*           for asbugs@watson; Fri, 10 Jun 94 06:26:04 -0400
--* Received: from inf.ethz.ch by watson.ibm.com (IBM VM SMTP V2R3) with TCP;
--*    Fri, 10 Jun 94 06:26:03 EDT
--* Received: from vinci.inf.ethz.ch (bronstei@vinci.inf.ethz.ch [129.132.12.46]) by inf.ethz.ch (8.6.8/8.6.6) with ESMTP id MAA01291 for <asbugs@watson.ibm.com>; Fri, 10 Jun 1994 12:26:01 +0200
--* From: Manuel Bronstein <bronstei@inf.ethz.ch>
--* Received: (bronstei@localhost) by vinci.inf.ethz.ch (8.6.8/8.6.6) id MAA20114 for asbugs@watson.ibm.com; Fri, 10 Jun 1994 12:25:57 +0200
--* Date: Fri, 10 Jun 1994 12:25:57 +0200
--* Message-Id: <199406101025.MAA20114@vinci.inf.ethz.ch>
--* To: asbugs@watson.ibm.com
--* Subject: [9] file name 'pointer.as' causes compiler errors [pointer.as][0.35.0]

--@ Fixed  by:  PI   Thu Aug 4 11:09:27 EDT 1994 
--@ Tested by:  none 
--@ Summary:    `pointer.as' is the name of a file in aslib: these names should be never used (use ar vt libaslib.asl, libasdem.asl, etc. to verify) 

------------------------------- pointer.as ----------------------------------
--
-- This file does not compile ONLY if its name is exactly 'pointer.as'!
-- Furthermore, the error messages are rather cryptic in this case:
--
-- vinci.inf.ethz.ch{bronstei} 144: asharp pointer.as
-- "/a/home/rutishauser/ru2/asharp/base/sungcc/include/asmacros.as", line 4: (Error) (After Macro Expansion) Argument 1 of `nil?' did not match with any possible parameter type.
--
-- Expanded expression was: p @ % pretend Pointer
-- "/a/home/rutishauser/ru2/asharp/base/sungcc/include/asmacros.as", line 4: (Error) (After Macro Expansion) Argument 1 of `=' did not match with any possible parameter type.
--
-- Expanded expression was: p @ % pretend Pointer
-- "/a/home/rutishauser/ru2/asharp/base/sungcc/include/asbase.as", line 24: (Error) There are no suitable meanings for the operator `Segment'.
-- "pointer.as", line 29: (Error) (After Macro Expansion) Have determined 0 possible types for the expression.
-- Expanded expression was: nil$Pointer
--
-- It compiles ok if the file name is changed, but finding that out was
-- a major waste of time.

#include "aslib.as"

PointerTo(T:Type): BasicType with {
	address: T -> %;
	apply: % -> T;
	nil: %;
	nil?: % -> Boolean;
	set!: (%, T) -> T
} == add {
	macro Rep == P;
	macro R == Record(val:T);

	-- untagged union of Record and Nil
	P: with {
		nil?:    % -> Boolean;
		nilptr:  %;
		recptr:  R -> %;
		value:   % -> R;
		=:       (%, %) -> Boolean;
	} == add {
		macro Rep == Pointer;
		import from {Rep, Pointer};
		nil?(p: %):Boolean	== nil? rep p;
		nilptr:%		== per(nil$Pointer);
		recptr(r:R):%		== r pretend %;
		value(p:%):R		== p pretend R;
		(p:%) = (q:%):Boolean	== rep p = rep q;
	}

	import from {R, Rep};

	sample:%			== nil;
	(p:%) = (q:%):Boolean		== rep p = rep q;
	apply(p:OutPort, q:%):OutPort	== { nil? q => p("NIL"); p("0x*") };
	nil:%				== per nilptr;
	nil?(p:%):Boolean		== nil? rep p;
	address(x:T):%			== per recptr [x];
	apply(p:%):T			== value(rep p).val;
	set!(p:%, x:T):T		== value(rep p).val := x;
}

 
