Warning: currently there's a serious bug in flx: it does not rebuild if the *.flx file is changed. It is supposed to do that! You will need to use --force until I fix it!
Now: here is the beauty of Felix! //////////////////////////// sthe_name : = "@" sthe_name =># "(Prefix)"; typedef fun n"@" (T:TYPE) : TYPE => cptr[T]; typedef ptr[T] = &T; union cptr[T] = | nullptr | Ptr of &T; ctor[T] cptr[T]: &T -> @T = "$1"; // safe ctor[T] ptr[T]( px:@T) => let Ptr ?p = px in p; // match failure if null fun deref[T] (px:@T)=> *(px.ptr); // checked deref fun is_nullptr[T] (px:@T)=> match px with | nullptr => true | _ => false endmatch; ///////////////////////// Enforced NULL pointer checking in 9 lines of code without touching the compiler. The grammar production: sthe_name : = "@" sthe_name =># "(Prefix)"; is not necessary, it just fixes the precedence of the operator: without it also, @ is not a legal identifier so you would have to reuse one: I initially used "^" which is reminder of Pascal. Potential confusion with infix ^, but the resolution is similar to * and - which also have infix and prefix forms. The notation: n"@" used in the typedef is a little secret of Felix: any string can be used as an identifier with that notation. By the grammar we have to define a function named "@" but it isn't a legal identifier, so we just force it. The typedefs introduced next: ptr, cptr, are there only because it is necessary for ctor definition. Ctors require an identifier as a typename. Multiple constructors can be made for any type from the same type, but you have to make typedefs so you can name them differently. This is how "complex" and "polar" are used to construct the same type (complex) from the same argument (double * double) but give different results. The actual cptr type is a TRICK. It depends on the representation to work. The conversion &T -> @T is safe so the function is an identity. The conversion @T -> &T is checked by tricking the compiler into generating a match failure. Note that "let Ptr ?p = px in p" is just match px with | Ptr ?p => p | _ => assert 'match_failure' endmatch;" If you screw up you get this: Match Failure Felix location: /Users/johnskaller/felix/./abc.flx 6[27]-6[47] C++ location : /Users/johnskaller/.felix/cache/text//Users/johnskaller/felix/./abc.cpp 68 which tells you you have a null ptr issue, but not where it is :) // test code var x = nullptr[int]; fun str[T] (px: @T) => match px with | nullptr => "NULLPTR" | Ptr ?p => "Address " + p.address.str endmatch ; println$ str x; //println$ *x; var a = 42; x = Ptr (&a); println$ str x;; println$ *x; const null: cptr[int] = "NULL"; println$ is_nullptr null; -- john skaller skal...@users.sourceforge.net ------------------------------------------------------------------------------ Try before you buy = See our experts in action! The most comprehensive online learning library for Microsoft developers is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3, Metro Style Apps, more. Free future releases when you subscribe now! http://p.sf.net/sfu/learndevnow-dev2 _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language