Standardized CompileError
This commit is contained in:
@@ -22,6 +22,7 @@ Kiss is a work in progress. (See: [Who should use Kiss?](#who-should-use-kiss))
|
||||
- [ ] [Reader macros](https://gist.github.com/chaitanyagupta/9324402)
|
||||
- [ ] Plug-and-play with every pure-Haxe library on Haxelib
|
||||
- [ ] Smooth FFI with any non-Haxe library you can find or write Haxe bindings for
|
||||
- [ ] helpful compiler errors
|
||||
|
||||
**Extra goodies:**
|
||||
|
||||
|
41
src/kiss/CompileError.hx
Normal file
41
src/kiss/CompileError.hx
Normal file
@@ -0,0 +1,41 @@
|
||||
package kiss;
|
||||
|
||||
import kiss.Reader;
|
||||
import kiss.List;
|
||||
|
||||
using kiss.Reader;
|
||||
|
||||
class CompileError {
|
||||
var exps:List<ReaderExp>;
|
||||
var message:String;
|
||||
|
||||
function new(exps:Array<ReaderExp>, message:String) {
|
||||
this.exps = exps;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public static function fromExp(exp:ReaderExp, message:String) {
|
||||
return new CompileError([exp], message);
|
||||
}
|
||||
|
||||
public static function fromArgs(exps:Array<ReaderExp>, message:String) {
|
||||
return new CompileError(exps, message);
|
||||
}
|
||||
|
||||
public function toString() {
|
||||
var posPrefix = switch (exps.length) {
|
||||
case 1:
|
||||
exps[0].pos;
|
||||
default:
|
||||
var justLineAndColumnIdx = exps[-1].pos.indexOf(":") + 1;
|
||||
exps[0].pos + '-' + exps[-1].pos.substr(justLineAndColumnIdx);
|
||||
}
|
||||
|
||||
return '\nKiss compilation failed!\n'
|
||||
+ posPrefix
|
||||
+ ": "
|
||||
+ message
|
||||
+ "\nFrom:"
|
||||
+ [for (exp in exps) exp.def.toString()].toString();
|
||||
}
|
||||
}
|
@@ -6,6 +6,7 @@ import kiss.Reader;
|
||||
import kiss.Types;
|
||||
import kiss.Helpers;
|
||||
import kiss.Stream;
|
||||
import kiss.CompileError;
|
||||
|
||||
using kiss.Reader;
|
||||
using StringTools;
|
||||
@@ -40,13 +41,13 @@ class FieldForms {
|
||||
case Symbol(name) | TypedExp(_, {pos: _, def: Symbol(name)}):
|
||||
name;
|
||||
default:
|
||||
throw 'The first argument to $formName at ${nameExp.pos} should be a variable name or typed variable name';
|
||||
throw CompileError.fromExp(nameExp, 'The first argument to $formName should be a variable name or typed variable name.');
|
||||
};
|
||||
}
|
||||
|
||||
static function varOrProperty(formName:String, position:Position, args:Array<ReaderExp>, convert:ExprConversion):Field {
|
||||
if (args.length < 2 || args.length > 3) {
|
||||
throw '$formName with $args at $position has wrong number of arguments';
|
||||
throw CompileError.fromArgs(args, '$formName has wrong number of arguments');
|
||||
}
|
||||
|
||||
var name = fieldName(formName, args[0]);
|
||||
|
@@ -9,6 +9,7 @@ import kiss.FieldForms;
|
||||
import kiss.SpecialForms;
|
||||
import kiss.Macros;
|
||||
import kiss.Types;
|
||||
import kiss.CompileError;
|
||||
|
||||
typedef KissState = {
|
||||
className:String,
|
||||
@@ -24,42 +25,48 @@ class Kiss {
|
||||
Build a Haxe class from a corresponding .kiss file
|
||||
**/
|
||||
macro static public function build(kissFile:String):Array<Field> {
|
||||
var classFields = Context.getBuildFields();
|
||||
var className = Context.getLocalClass().get().name;
|
||||
try {
|
||||
var classFields = Context.getBuildFields();
|
||||
var className = Context.getLocalClass().get().name;
|
||||
|
||||
var stream = new Stream(kissFile);
|
||||
var stream = new Stream(kissFile);
|
||||
|
||||
var k = {
|
||||
className: className,
|
||||
readTable: Reader.builtins(),
|
||||
fieldForms: FieldForms.builtins(),
|
||||
specialForms: SpecialForms.builtins(),
|
||||
macros: Macros.builtins(),
|
||||
convert: null
|
||||
}
|
||||
k.convert = readerExpToHaxeExpr.bind(_, k);
|
||||
|
||||
while (true) {
|
||||
stream.dropWhitespace();
|
||||
if (stream.isEmpty())
|
||||
break;
|
||||
var position = stream.position();
|
||||
var nextExp = Reader.read(stream, k.readTable);
|
||||
#if test
|
||||
trace(nextExp);
|
||||
#end
|
||||
// The last expression might be a comment, in which case None will be returned
|
||||
switch (nextExp) {
|
||||
case Some(nextExp):
|
||||
var field = readerExpToField(nextExp, position, k);
|
||||
if (field != null)
|
||||
classFields.push(field);
|
||||
case None:
|
||||
stream.dropWhitespace(); // If there was a comment, drop whitespace that comes after
|
||||
var k = {
|
||||
className: className,
|
||||
readTable: Reader.builtins(),
|
||||
fieldForms: FieldForms.builtins(),
|
||||
specialForms: SpecialForms.builtins(),
|
||||
macros: Macros.builtins(),
|
||||
convert: null
|
||||
}
|
||||
}
|
||||
k.convert = readerExpToHaxeExpr.bind(_, k);
|
||||
|
||||
return classFields;
|
||||
while (true) {
|
||||
stream.dropWhitespace();
|
||||
if (stream.isEmpty())
|
||||
break;
|
||||
var position = stream.position();
|
||||
var nextExp = Reader.read(stream, k.readTable);
|
||||
#if test
|
||||
trace(nextExp);
|
||||
#end
|
||||
// The last expression might be a comment, in which case None will be returned
|
||||
switch (nextExp) {
|
||||
case Some(nextExp):
|
||||
var field = readerExpToField(nextExp, position, k);
|
||||
if (field != null)
|
||||
classFields.push(field);
|
||||
case None:
|
||||
stream.dropWhitespace(); // If there was a comment, drop whitespace that comes after
|
||||
}
|
||||
}
|
||||
|
||||
return classFields;
|
||||
} catch (err:CompileError) {
|
||||
Sys.println(err);
|
||||
Sys.exit(1);
|
||||
return null; // Necessary for build() to compile
|
||||
}
|
||||
}
|
||||
|
||||
static function readerExpToField(exp:ReaderExp, position:Position, k:KissState):Null<Field> {
|
||||
|
Reference in New Issue
Block a user