Skip to content

[FEATURE] final keyword #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: funkin-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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