Progress
This article summarizes what works
and what doesn't yet work in Tusk.
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.
- with statements.
- label or goto statements.
- absolute variable declarations.
- Forward declarations of pointer types.
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 if…then…else 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).
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 for‥in 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 for‥in loops)
- Specific Records…
- TDSCharSet
- Rational
- BigRational
- BigInt
- BigCardinal
- TDuration
- TMoment
- Int96
- UInt96
- TSQLExpr
- Anonymous methods.
- Fluent SQL.
- 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.
- Aliases to existing types.
- Enumerations.
- Sets.
- Dynamic arrays.
- Pointers.
- Anonymous methods.
- Records (fields only for now; no methods or properties).
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.
Tusk's support for functions is evolving.
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).
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.
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).
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.
Tusk currently supports only two Delphi directives…
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.
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.
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