We are considering making several enhancements to the Slick-C language for a future release of SlickEdit. The following paper gives an overview of the changes, with examples. We are posting this specification here in order to get feedback on the languages changes from our users.
Note: This discussion is to address changes to the Slick-C language. Do not post any comments about about other languages (Java, C#, Python,Perl,Ruby, JavaScript, TCL, etc.) unless it is to point out a nice feature that could be added to Slick-C. Please post about adding support for other macro languages on another thread.
A significant portion of SlickEdit is written in Slick-C, so the language is not going away anytime soon. We are simply trying to make it more modern and powerful.
Table of Contents- Principles
- := operator
- Enumerated types
- #import directive
- #pragma option(strictprotos)
- Namespaces
- Interfaces
- Classes
- Introspection
- New reserved words
- Features not addressed
Principles- Continued backward compatibility with almost all existing Slick-C code
- Maintain close language design relationship with foundation languages C/C++, C#, Java, and Objective-C
- Use or extend existing mechanisms instead of re-inventing (For example, do not rewrite the interpreter).
- Practicality -- focus on important features that are reasonably easy to add in a short time frame, which leaves us more time to spend adding features to SlickEdit.
- Performance -- Do not introduce features that carry significant run-time costs. Also focus on features that will improve performance compared to certain idioms being used in Slick-C now.
The := OperatorThe := operator is used as follows:
id := expr;
In this statement, "id" is declared as a local variable with the same type as "expr".
b := false; // boolean b = false;
i := 0; // int i = 0;
j := i; // int j = i;
s := "test"; // _str s = "test";
p := &s; // _str *p = &s;
c := _process_comment(line); // COMMENT_TYPE c=_process_comment(line);
p := &obj; // Object *p = &obj;
fp := func; // int (*fp)() = func;
x := y := 0; // int x=0; int y=0;
for (a:=1; a<10; ++a); // count to 10
Enumerated TypesSlick-C enumerated types are going to be very much like C enumerated types, with the possible exception of having relaxed type checking with respect to arithmetic and bit operations.
enum BasicOptions {
OPTION1=1,
OPTION2,
OPTION3,
};
In addition, Slick-C enumerated types are going to introduce enumerated type flags, a convenient way to create a set of bit flags.
enum_flags OptionFlags {
FLAG1=0x4,
FLAG2, // 0x8
FLAG3, // 0x10
FLAGS_ALL=FLAG1|FLAG2|FLAG3
};
#import Directive#import is a preprocessing directive but it is more than a #include, in that it does the following:
- Imports all public declarations from a Slick-C module.
- Uses an implicit header guard to prevent recursive or multiple importation of the same module.
When processing a #import, the following rules will be in effect.
- All function definitions are treated as prototypes.
- Global variable definitions are treated as declarations.
- Static globals are ignored.
- Forms, menus, event tables and event handlers are ignored.
- #includes continue to be treated as part of the #import.
#import “stdcmds.eâ€
#import “slickedit/stringutil.eâ€
#import “slickedit/search.shâ€
#pragma option(strictprotos,on)Currently, when the Slick-C compiler encounters a function call to a previously undefined function, it assumes that the function is a global function. The function call is resolved at link time, and an error will show up at run time if the function does not exist or is not provided enough parameters.
With this option enabled, all function calls will require the function to be previously declared or imported.
This pragma will be off by default, however it's use will be strongly encouraged for new Slick-C code that uses namespaces and classes.
NamespacesSlick-C namespaces will use "." instead of "::". Slick-C will support two types of namespace declarations. Slick-C will not allow un-named namespace declarations.
// module-wide (like Java)
namespace slickedit.tagging;
// scoped namespace declaration (like C++ and C#)
namespace slickedit.search {
. . .
}
Namespace imports will use the C++ style using syntax.
// pull all symbols from slickedit.tagging into current scope
using namespace slickedit.tagging;
// pull one symbol from slickedit.search into scope
using slickedit.search.Regex;
// qualified access to a symbol in the namespace
slickedit.diff.Diff( f1, f2 );
InterfacesInterfaces will use Java-like syntax. They will not allow constructors, destructors, or member variables, only prototypes. Interfaces may inherit from other interfaces.
interface CommunicationDevice {
void talk();
void hangup();
};
ClassesClasses will use Java-like syntax.
class Phone : CommunicationDevice {
Phone(_str number=“â€) { }
~Phone() { }
void talk() {
}
void hangup() {
}
static void getOperator() {
}
protected typeless dialer;
private typeless line;
private static typeless operator = null;
};
A few notes about Slick-C classes:
- Classes can inherit from classes and/or interfaces.
- A class can only extend one class, but it may implement multiple interfaces.
- There will be no "extends" or "implements" keywords.
- Classes will not be allowed to derive from "struct" types.
- The default access level will be public. There will be a "public" keyword, but it will essentially do nothing.
- Class members will support "protected" and "private", as usual.
- There will be no concept of a package scope as there is in Java. While this is a useful feature, it is largely misunderstood by the majority of Java programmers, causing more problems that good.
- Member functions will be virtual by default, except for "static" member functions, as usual.
- "static" member variables may have initializers.
- "extern" member function prototypes are to be implemented in a DLL.
- A class is allowed one and only one constructor.
- If a class constructor takes arguments, they must have defaults.
- No explicit calls to new or delete (no new or delete keywords).
- No function overloading -- maybe for a future release.
- No operator overloading.
- No friend relationships.
- No templates or generics -- maybe for a future release.
- No final and no const.
- No C# style properties or delegates.
- No default root "object" class.
- No static constructors -- maybe for a future release.
The life-span of a Slick-C class instance is identical to that of a similar Slick-C struct. There will be no "new" and "delete" operators.
// construct an instance of a class, like C++
C1 a;
C1 b;
// assign a class instance to another (deep copy)
a = b;
// An array of class instances.
// Constructor not called here.
C1 array[];
// Constructor called with no args
// followed by deep copy.
array[1] = a;
IntrospectionSlick-C will support introspection of struct and class instances through the following new built-in functions. In each the functions below, "index" can be either an integer index, or a string containing the field or method name.
v._typename()
v._fieldindex(name)
v._fieldname(i)
v._getfield(index)
v._setfield(index,value)
v._findmethod(name)
v._callmethod(index)
v._instanceof(name)
The C++ API for Slick-C will be extended to include the following functions.
vsHvarTypename(hvar)
vsHvarFieldIndex(hvar,name)
vsHvarFieldName(hvar,i)
vsHvarGetField(hvar,index)
vsHvarGetFieldByName(hvar,name)
vsHvarSetField(hvar,index,value)
vsHvarSetFieldByName(hvar,name,value)
vsHvarFindMethod(hvar,name)
vsHvarCallMethod(hvar,index,args)
vsHvarCallMethodByName(hvar,name,args)
vsHvarInstanceOf(hvar,name)
vsHvarConstruct(name,args)
New Reserved WordsThe following keywords will be made reserved. Old code that uses any of these keywords as function names, variable names, or any other type of identifier will no longer compile.
- namespace
- using
- interface
- class
- public
- protected
- private
- extern
The following identifiers will be made reserved as built-in functions.
- _typename
- _fieldindex
- _fieldname
- _setfield
- _getfield
- _findmethod
- _callmethod
- _instanceof
Features Not AddressedThe following modern language features are not going to be considered for Slick-C.
- Exception handling -- extremely big wormhole to go down and potential performance issues.
- Generics or templates -- maybe for a future, future release.
- Function overloading -- maybe for a future, future release.
- Static constructors -- maybe for a future, future release.