Changeset d414664
- Timestamp:
- May 1, 2024, 4:13:37 PM (7 months ago)
- Branches:
- master
- Children:
- 72713e5
- Parents:
- 35897fb
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/jiada_liang_MMath/CFAenum.tex
r35897fb rd414664 335 335 336 336 \section{Enum Trait} 337 A typed enum comes with traits capture enumeration charastics and helper functions. 338 337 The header file @<enum.hfa>@ defines traits implemented by, and sets of operators and helper functions defined for enum. 338 339 \begin{figure} 340 \small 339 341 \begin{cfa} 340 342 forall(E) trait Bounded { … … 343 345 }; 344 346 \end{cfa} 345 \CFA enums satisfy Bounded trait thanks to the compiler implementing lowerBound() and upperBound(), with 346 lowerBound() returning the first enumerator and upperBound() return the last. 347 347 \caption{f:Bounded Trait} 348 \label{f:BoundedTrait} 349 \end{figure} 350 351 \CFA enums satisfy Bounded trait thanks to the default implemention of @lowerBound()@ and @upperBound()@, with 352 @lowerBound()@ returning the first enumerator and @upperBound()@ returning the last. 353 354 \begin{figure} 355 \small 348 356 \begin{cfa} 349 357 Workday day1 = lowerBound(); // Monday 350 358 Planet lastPlanet = upperBound(); // NEPTUNE 351 359 \end{cfa} 352 353 Because lowerBound() and upperBound() are overloaded with return types only, calling either functions 354 in a null context cause type ambiguity if than one type implementing Bounded traits, including typed enumerations. 355 \begin{cfa} 356 Workday day1 = lowerBound(); // Okay because rhs hints lowerBound() to return a Workday 360 \caption{f:Bound Functions} 361 \label{f:BoundFunctions} 362 \end{figure} 363 364 @lowerBound()@ and @upperBound()@ are overloaded with return types only. Calling either functions 365 without a context can result in type ambiguity if more than one types implement the functions from the @Bounded@ traits. 366 Because \CFA enum types implements @Bounded@, multiple type enumerations in the same lexical scope will 367 cause ambiguity on @lowerBound()@ and @upperBound()@ \see{\VRef{f:BoundFunctions} }. 368 369 \begin{figure} 370 \small 371 \begin{cfa} 372 // lowerBound(); // Error because both Planet and Workday implement Bounded 373 Workday day1 = lowerBound(); // Okay because type of day1 hints lowerBound() to return a Workday 357 374 void foo(Planet p); 358 foo( upperBound() ); Okay because foo's parameter give type hint 359 // lowerBound(); // Error because both Planet and Workday implements Bounded 360 \end{cfa} 361 375 foo( upperBound() ); Okay because foo expects value with type Planet as parameter 376 \end{cfa} 377 \caption{Bound Function ambiguity} 378 \label{f:BoundAmbiguity} 379 \end{figure} 380 381 \begin{figure} 382 \small 362 383 \begin{cfa} 363 384 forall(E | Bounded(E)) trait Serial { … … 368 389 }; 369 390 \end{cfa} 370 A Serial type can be mapped to a sequnce of integer. For enum types, fromInstance(E e) is equivalent to 371 posE(E e). Enumerations implement fromInt(), succ(), and pred() with bound() check. 372 For an enum declares N enumerators, fromInt(i) returns the ith enumerator of type E if $0 \leq i < N$. 373 If e is the i-th enumerator, succ(e) returns the i+1-th enumerator if $e != upperBound()$ and pred(e) 374 returns the i-1-th enumerator $e != lowerBound()$. \CFA compile gives an error if bound check fails. 375 391 \caption{Bounded Trait} 392 \label{f:BoundedTrait} 393 \end{figure} 394 395 A Serial type is a @Bounded@ type where elements can be mapped to an integer sequence. 396 A serial type @T@ can project to the integer type: an instance of type T has a corresponding integer value, 397 but the inverse may not be possible, and possible requires a bound check. 398 399 The mapping from a serial type to integer is defined as @fromInstance(E e)@. 400 For enum types, @fromInstance(E e)@ is equivalent to getting the position of e. 401 The inverse of @fromInstance(E e)@ is @fromInt(unsigned i)@ and \CFA implements it with a bound check. 402 For an enum @E@ declares N enumerators, @fromInt(i)@ returns the $i-1_{th}$ enumerator if $0 \leq i < N$, or error otherwises. 403 404 The Serial trait provides interface functions @succ(E e)@ and @pred(E e)@ as members of a serial type are consecutive and ordinal. 405 If @e@ is the $i_{th}$ enumerator, @succ(e)@ returns the $i+1_{th}$ enumerator when $e != upperBound()$, and @pred(e)@ 406 returns the $i-1_{th}$ enumerator when $e != lowerBound()$. 407 \CFA compiler gives an error if the result of the operation is out the domain of type @T@. 408 409 \begin{figure} 410 \small 376 411 \begin{cfa} 377 412 forall(E, T) trait TypedEnum { … … 381 416 }; 382 417 \end{cfa} 383 384 The TypedEnum trait capture three basic attributes of type enums. TypedEnum asserts two types E and T, with T being the base type of enumeration E. 385 With an assertion on TypedEnum, we can implement functions for all type enums. 386 418 \caption{Type Enum Trait} 419 \label{f:TypeEnumTrait} 420 \end{figure} 421 422 The @TypedEnum@ trait captures three basic attributes of a type enum: value, label, and position. 423 TypedEnum asserts two types @E@ and @T@, with @T@ being the base type of enumeration @E@. 424 Implementing functions for general type enums is possible by asserting @TypeEnum(E, T)@. 425 426 \begin{figure} 427 \small 387 428 \begin{cfa} 388 429 forall( E, T | TypeEnum(E, T)) … … 392 433 printEunm(MARS); 393 434 \end{cfa} 435 \caption{Implement Functions for Enums} 436 \label{f:ImplementEnumFunction} 437 \end{figure} 394 438 395 439 @<enum.hfa>@ overwrites comparison operators for type enums. 440 \begin{figure} 441 \small 396 442 \begin{cfa} 397 443 forall(E, T| TypedEnum(E, T)) { 398 444 // comparison 399 int ?==?(E l, E r); 400 int ?!=?(E l, E r); 401 int ?!=?(E l, zero_t); 402 int ?<?(E l, E r); 403 int ?<=?(E l, E r); 404 int ?>?(E l, E r); 405 int ?>=?(E l, E r); 406 } 407 \end{cfa} 408 These overloaded operators are not defined if the file is not included. 409 In this case, the compiler converts an enumerator to its value, and applies the operators 410 if they are defined for the value type T. 411 445 int ?==?(E l, E r); // returns True if l and r are the same enumerator 446 int ?!=?(E l, E r); // returns True if l and r are the different enumerator 447 int ?!=?(E l, zero_t); // return True if l is not the first enumerator 448 int ?<?(E l, E r); // return True if l is an enuemerator before r 449 int ?<=?(E l, E r); // return True if l==r or l<r 450 int ?>?(E l, E r); // return True if l is an enuemrator after r 451 int ?>=?(E l, E r); // return True if l>r or l==r 452 } 453 \end{cfa} 454 \caption{Enum Operators} 455 \label{f:EnumOperators} 456 \end{figure} 457 The overloaded operators in \ref{f:EnumOperators} are defined when and only when the header @<enum.hfa>@ is included. 458 If not, the compiler converts an enumerator to its value, and applies the operators defined for the value type @T@. 459 460 \begin{figure} 461 \small 412 462 \begin{cfa} 413 463 // if not include <enum.hfa> 414 464 enum(int) Fruits { 415 APPLE = 2, BANANA=1 , CHERRY=2416 }; 417 APPLE == CHERRY; // True because they have the same Value465 APPLE = 2, BANANA=10, CHERRY=2 466 }; 467 APPLE == CHERRY; // True because valueE(APPLE) == valueE(CHERRY) 418 468 #include <enum.hfa> 419 469 APPLE == CHERRY; // False because they are different enumerator 420 470 \end{cfa} 471 \caption{Include <enum.hfa>} 472 \label{f:IncludeHeader} 473 \end{figure} 474 475 An enumerator returns its @position@ by default. In particular, 476 @printf(...)@ from @<stdio.h>@ functions provides no context to its parameter type, 477 so it prints @position@. 478 479 On the other hand, the pipeline operator @?|?(ostream os, E enumType)@ provides type context for type @E@, and \CFA 480 has overwritten this operator to prints enumeration @value@ over @position@. 481 \begin{figure} 482 \small 483 \begin{cfa} 484 printf("Position of BANANA is \%d", BANANA); // Postion of BANANA is 1 485 sout | "Value of BANANA is " | BANANA; // Value of BANANA is 10 486 \end{cfa} 487 \caption{Print Enums} 488 \label{f:PrintEnum} 489 \end{figure} 490 491 Programmers can overwrite this behaviour by overloading the pipeline operator themselve.
Note: See TracChangeset
for help on using the changeset viewer.