Sage
Tusk Language
Welcome to Sage
Volume (30%) Hide Volume
Topics
Progress
This article summarizes what works and what doesn't yet work in Tusk.

Statements

Tusk supports the following statements…
  • type declarations.
  • const declarations (with type inference).
  • var declarations (with type inference).
  • Assignment statements.
  • Function and procedure calls (with optional parentheses).
  • if statements.
  • case statements (including a strict option).
  • while loops.
  • repeat loops.
  • for := loops (with optional inline variable).
  • for in loops (with optional inline variable and optional index variable).
  • raise statements.
  • try/finally and try/except statements.

Tusk does not yet support…
  • with statements.
  • label or goto statements.
  • absolute variable declarations.
  • Forward declarations of pointer types.

Operators

Tusk supports these operators…
  • Binary: +, -, *, /, div, mod.
  • Binary: and, or, and xor (logical and bitwise).
  • Binary: =, <>, <, >, <=, >=.
  • Binary: shl and shr.
  • Binary: . operator (with implicit pointer dereferencing).
  • Unary: +, -, not (logical and bitwise).
  • The ifthenelse ternary operator.
  • in, is and as.
  • is not and not in.
  • Prefix type casts: x := Double(y);
    (Tusk doesn't yet support L-Value casts, as in Double(y) := 1.2;).
  • [] (array indexing) single dimension only, for now.
  • ^ (dereference pointer).
  • @ (address-of).
  • ** (exponentiation).
  • @@ (suppress implicit function call).

Types

Tusk supports these Delphi data types (not exhaustive)…
  • Integers: Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32, UInt64, Integer, Cardinal, NativeInt, NativeUInt, ShortInt, Byte, SmallInt, Word.
  • Floats: Single, Double, Currency, Decimal.
  • Boolean.
  • string, AnsiString, and UnicodeString.
  • Char, AnsiChar, and WideChar.
  • TSysCharSet and TDSCharSet.
  • PChar and PAnsiChar.
  • Variant.
  • Variant arrays.
  • Dynamic arrays.
  • Enums (including scoped enums).
  • Sets (of enum, Byte, Int8, and AnsiChar).
  • Pointers including PTypeInfo and PTypeData.
  • Interfaces…
    • Methods
    • Properties
    • Array properties (one dimension only, for now)
    • Default array properties
    • GetEnumerator method (supporting forin loops)
    • Generic interfaces, including IMap<K,V>, IList<T>, ISet<T>, IVector<T>, etc.
  • Records…
    • Fields
    • Instance methods
    • Instance properties
    • Instance array properties
    • Class methods
    • Class properties
    • Class array properties
    • Constructors
    • Type conversions (implicit and explicit)
    • Operator overloads (unary and binary)
    • Nested constants (defined within a record)
    • Nested types (defined within a record)
    • GetEnumerator method (supporting forin loops)
  • Specific Records…
    • TDSCharSet
    • Rational
    • BigRational
    • BigInt
    • BigCardinal
    • TDuration
    • TMoment
    • Int96
    • UInt96
    • TSQLExpr
  • Anonymous methods.
  • Fluent SQL.

Tusk does not yet support…
  • Classes or class references.
  • WideString (use string instead).
  • Short strings (use AnsiString instead).
  • Global procedural types (tkProcedure kind).
  • Pointers to class methods (tkMethod kind).
  • Static arrays (use dynamic arrays instead).
  • Generic records.
  • Generic record methods.
  • Generic types (other than dynamic arrays and interfaces).
  • Type helpers (methods/properties on types other than records, classes, and interfaces, such as string or Double).
  • Structured constants, like const p: TPoint = (x:1; y:2);
  • Multi-dimensional array properties.
  • The Real and Real48 types.

Tusk programs can define new data types…
  • Aliases to existing types.
  • Enumerations.
  • Sets.
  • Dynamic arrays.
  • Pointers.
  • Anonymous methods.
  • Records (fields only for now; no methods or properties).

Highlights

Tusk already supports most of the contents of several Delphi RTL and Dimeric Utility units…
  • System, SysUtils, Variants, Windows, DateUtils, Math, etc.
  • DSGenUtil, DSStringUtil, DSMathUtil.
  • DSStringList, DSSet, and DSList, including TVarExpr.
  • DSPropertyBag (except for overloads taking MiniCalc expressions or environments).
  • DSStreams, DSTypedStreams, and DSLog.
  • DSJSONUtil.
  • DSDB and VirtualDB.
  • DSFileUtil and DSLaunchUtil.
  • DSFTP and DSSSH.
  • DSDecimal, DSRational, and DSInt96.
  • DSLock and DSSortUtil.
  • DSRegExpr.

A complete list of units is available here.

Functions

Tusk's support for functions is evolving.

Exposed Delphi Routines

For routines defined in Delphi, Tusk currently supports…
  • Optional parentheses when calling zero-argument functions and procedures.
  • Default parameters.
  • const, var, and out.
  • Open array parameters.
  • Overloaded global procedures / functions.
  • Interface methods (including generics).
  • Overloaded interface/record methods.
  • Anonymous procedures and functions.
  • Low-level memory management
    (New / Dispose, GetMem / ReallocMem / FreeMem, etc).

Routines Written in Tusk

For routines defined in Tusk, the following are supported…
  • Optional parentheses.
  • Default parameters.
  • const, var, and out.
  • Exit and Result.
  • Global procedures / functions.
  • Nested procedures / functions.
  • Forward declared functions (for mutually recursive functions).
  • Static scoping, like Delphi (not dynamic scoping, like MiniCalc).
  • Anonymous procedures and functions.

Lifetime of Temporaries

In Delphi, invisible temporary managed variables are finalized when the procedure or function exits. For example…

procedure Demo; begin Writeln('Hello'); CallOnceWrapper( procedure begin Writeln('Cleanup'); end); Writeln('Goodbye'); end;

In Delphi, the above prints…

Hello Goodbye Cleanup

This is because CallOnceWrapper returns a TProc that, when its last reference goes away, calls Writeln.

In Tusk, however, invisible managed variables are finalized as soon as they're no longer needed. Thus, in Tusk, the above code prints…

Hello Cleanup Goodbye

When consistent behavior is desired, simply use an explicit variable…

procedure Demo; begin Writeln('Hello'); var Cleanup := CallOnceWrapper( procedure begin Writeln('Cleanup'); end); Writeln('Goodbye'); end;

This does not change the behavior in Delphi, but in Tusk, it ensures that the cleanup happens at the end of the procedure (matching Delphi's behavior).

Not Yet Supported

Tusk doesn't yet support…
  • Forward declared overloaded functions written in Tusk (Tusk functions may be overloaded or forward declared, but not both).
  • Generic functions written in Tusk.
  • Open array params for functions written in Tusk.
  • Open array params using the out keyword.
  • const [ref] parameters.
  • Untyped parameters.
  • array of const parameters (used by Format and related functions).
  • The optional MinWidth and DecPlaces specifiers used with Write and Writeln (more details here).
  • Assigning a function result using the function's name, as in… function f: Integer; begin f := 123; end; The work-around is easy: assign to Result instead.
  • Passing a single value where an open array of values is required.

Directives

Tusk currently supports only two Delphi directives…
  • {$ScopedEnums} (link).
  • {$Include <filename>} (link).

Tusk does not yet support any of the following Delphi directives…
  • {$I <filename>} (link) – use {$Include <filename>} instead.
  • {$PointerMath} (link) – Pointer math is always on in Tusk.
  • {$RangeChecks} / {$R} (link) – Range checking is always on in Tusk.
  • {$OverflowChecks} / {$Q} (link) – Overflow checking is always on in Tusk.
  • {$RealCompatibility} (link) – Tusk does not support the Real type; use Double or Single instead.
  • {$TextBlock} (link).
  • {$TypedAddress} / {$T} (link) – Type-checked pointers are always on in Tusk.
  • {$WritableConst} / {$J} (link) – Typed constants are not writable in Tusk.
  • {$ZeroBasedStrings} (link) – Strings are always one-based in Tusk, matching traditional Pascal and Delphi behavior, the current default behavior of Delphi, global string handling functions in the Delphi RTL, and string handling functions in our Utility folder.
  • {$MinEnumSize} / {$Z} (link) – Enums defined in Tusk use the smallest possible size, matching the default behavior of the Delphi compiler.
  • {$IOChecks} / {$I} (link) – Input/Output checks are controlled by the host application; Tusk code cannot alter this at runtime.
  • {$HighCharUnicode} (link) – Tusk behaves as if this directive is on, and AnsiChar literals are limited to the range #0..#255.
  • {$Align} / {$A} (link) – Records defined in Tusk use the default alignment of the Delphi compiler (8-byte), except for packed records, which do not align fields.
  • {$BoolEval} / {$B} (link) – Tusk always uses Boolean short-circuit evaluation.
  • {$IfDef} / {$If} / {$Else} / {$Define} / {$Undef} / {$IfOpt} / etc. – Tusk will hopefully support these conditional directives in the near future.
  • {$Hints} / {$Warn} / {$Warnings} / etc. – Tusk will hopefully support these conditional directives in the near future.
  • {$Message} (link) – Tusk will hopefully support this directive in the near future.
  • All other Delphi compiler directives.

Config Files

Tusk has preliminary support for Config files, using the extension .tkconfig instead of .dsconfig.

The basics are working, but the following have not been tackled yet…
  • DBConfig (storing .tkconfig files in the database).
  • The include :database directive.

Runtime Library

Tusk exposes a fair amount of Delphi's Runtime Library, as well as some of our own utility libraries.

For more details, please see the Tusk Runtime Library volume.

Tusk does not yet implement the following features that MiniCalc offers…
  • #api FluentSQL.
  • Code Insight (used in DSEdit and VDB Explorer).
  • Debugging in DSEdit (breakpoints, etc).

Last Modified: 2/15 9:51:46 am
In this article (top)  View article's Sage markup
2/15 9:51:46 am