Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions hscript/Expr.hx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ enum Expr {
EConst( c : Const );
EIdent( v : String );
EVar( n : String, ?t : CType, ?e : Expr );
EFinal( n : String, ?t : CType, ?e : Expr );
EParent( e : Expr );
EBlock( e : Array<Expr> );
EField( e : Expr, f : String );
Expand Down Expand Up @@ -174,4 +175,5 @@ typedef VarDecl = {
var set : Null<String>;
var expr : Null<Expr>;
var type : Null<CType>;
var isfinal : Null<Bool>;
}
11 changes: 9 additions & 2 deletions hscript/Interp.hx
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ private enum Stop {
class Interp {

public var variables : Map<String,Dynamic>;
var locals : Map<String,{ r : Dynamic }>;
var locals : Map<String,{ r : Dynamic, ?isfinal : Bool }>;
var binops : Map<String, Expr -> Expr -> Dynamic >;

var depth : Int;
var inTry : Bool;
var declared : Array<{ n : String, old : { r : Dynamic } }>;
var declared : Array<{ n : String, old : { r : Dynamic, ?isfinal : Bool } }>;
var returnValue : Dynamic;

#if hscriptPos
Expand Down Expand Up @@ -122,6 +122,7 @@ class Interp {
switch( Tools.expr(e1) ) {
case EIdent(id):
var l = locals.get(id);
if( l != null && l.isfinal && l.r != null) return error(EInvalidAccess(id));
if( l == null )
setVar(id,v)
else
Expand Down Expand Up @@ -155,6 +156,7 @@ class Interp {
case EIdent(id):
var l = locals.get(id);
v = fop(expr(e1),expr(e2));
if( l != null && l.isfinal && l.r != null) return error(EInvalidAccess(id));
if( l == null )
setVar(id,v)
else
Expand Down Expand Up @@ -189,6 +191,7 @@ class Interp {
case EIdent(id):
var l = locals.get(id);
var v : Dynamic = (l == null) ? resolve(id) : l.r;
if( l != null && l.isfinal && l.r != null) return error(EInvalidAccess(id));
if( prefix ) {
v += delta;
if( l == null ) setVar(id,v) else l.r = v;
Expand Down Expand Up @@ -311,6 +314,10 @@ class Interp {
declared.push({ n : n, old : locals.get(n) });
locals.set(n,{ r : (e == null)?null:expr(e) });
return null;
case EFinal(n,_,e):
declared.push({ n : n, old : locals.get(n) });
locals.set(n,{ r : (e == null)?null:expr(e), isfinal : true });
return null;
case EParent(e):
return expr(e);
case EBlock(exprs):
Expand Down
26 changes: 24 additions & 2 deletions hscript/Parser.hx
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ class Parser {
return switch( expr(e) ) {
case EBlock(_), EObject(_), ESwitch(_): true;
case EFunction(_,e,_,_): isBlock(e);
case EVar(_, t, e): e != null ? isBlock(e) : t != null ? t.match(CTAnon(_)) : false;
case EVar(_, t, e) | EFinal(_, t, e): e != null ? isBlock(e) : t != null ? t.match(CTAnon(_)) : false;
case EIf(_,e1,e2): if( e2 != null ) isBlock(e2) else isBlock(e1);
case EBinop(_,_,e): isBlock(e);
case EUnop(_,prefix,e): !prefix && isBlock(e);
Expand Down Expand Up @@ -614,6 +614,27 @@ class Parser {
}

mk(EVar(ident,t,e),p1,(e == null) ? tokenMax : pmax(e));
case "final":
var ident = getIdent();
var tk = token();
var t = null;
if( tk == TDoubleDot && allowTypes ) {
t = parseType();
tk = token();
}
var e = null;

switch (tk)
{
case TOp("="): e = parseExpr();
case TOp(_): unexpected(tk);
case TComma | TSemicolon: push(tk);
// Above case should be enough but semicolon is not mandatory after }
case _ if (t != null): push(tk);
default: unexpected(tk);
}

mk(EFinal(ident,t,e),p1,(e == null) ? tokenMax : pmax(e));
case "while":
var econd = parseExpr();
var e = parseExpr();
Expand Down Expand Up @@ -1225,7 +1246,7 @@ class Parser {
ret : inf.ret,
}),
};
case "var":
case "var" | "final":
var name = getIdent();
var get = null, set = null;
if( maybe(TPOpen) ) {
Expand Down Expand Up @@ -1256,6 +1277,7 @@ class Parser {
set : set,
type : type,
expr : expr,
isfinal : (id == "final")
}),
};
default:
Expand Down
7 changes: 7 additions & 0 deletions hscript/Printer.hx
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ class Printer {
add(" = ");
expr(e);
}
case EFinal(n, t, e):
add("final " + n);
addType(t);
if( e != null ) {
add(" = ");
expr(e);
}
case EParent(e):
add("("); expr(e); add(")");
case EBlock(el):
Expand Down
3 changes: 2 additions & 1 deletion hscript/Tools.hx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class Tools {
public static function iter( e : Expr, f : Expr -> Void ) {
switch( expr(e) ) {
case EConst(_), EIdent(_):
case EVar(_, _, e): if( e != null ) f(e);
case EVar(_, _, e) | EFinal(_, _, e): if( e != null ) f(e);
case EParent(e): f(e);
case EBlock(el): for( e in el ) f(e);
case EField(e, _): f(e);
Expand Down Expand Up @@ -64,6 +64,7 @@ class Tools {
var edef = switch( expr(e) ) {
case EConst(_), EIdent(_), EBreak, EContinue: expr(e);
case EVar(n, t, e): EVar(n, t, if( e != null ) f(e) else null);
case EFinal(n, t, e): EFinal(n, t, if( e != null ) f(e) else null);
case EParent(e): EParent(f(e));
case EBlock(el): EBlock([for( e in el ) f(e)]);
case EField(e, fi): EField(f(e),fi);
Expand Down