Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
4 changes: 3 additions & 1 deletion source/language.d
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,16 @@ final class AssignStatement : Statement
Type type;
VarExpression dest;
Expression expr;
bool isConst;

this (int lineId_, Type type_, VarExpression dest_, Expression expr_)
this (int lineId_, Type type_, VarExpression dest_, Expression expr_, bool isConst_ = false)
{
lineId = lineId_;
type = type_;
dest = dest_;
expr = expr_;
complexity = 1 + dest.complexity + expr.complexity;
isConst = isConst_;
}
}

Expand Down
9 changes: 8 additions & 1 deletion source/parser.d
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,13 @@ final class StatementParser
"indent does not match");
t.popFront ();

bool isConst = false;
if (!line.tokens.empty && line.tokens.front == "const")
{
isConst = true;
line.tokens.popFront();
}

auto var = cast (VarExpression) (parseExpression (line));
check (var !is null, line,
"assign statement detected but left side not parsed");
Expand Down Expand Up @@ -528,7 +535,7 @@ final class StatementParser
check (line.tokens.empty, line,
"extra token at end of line: " ~ line.tokens.front);

return new AssignStatement (line.lineId, type, var, cur);
return new AssignStatement (line.lineId, type, var, cur, isConst);
}

Statement parseStatement (string prevIndent)
Expand Down
51 changes: 43 additions & 8 deletions source/runner.d
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class Runner
}
}

long * varAddress (string name, bool canCreate = false)
long * varAddress (string name, bool canCreate = false, bool isConst = false)
{
foreach_reverse (ref cur; state)
{
Expand All @@ -128,11 +128,11 @@ class Runner
{
throw new Exception ("no such variable: " ~ name);
}
state.back.vars[name] = Var (0);
state.back.vars[name] = Var (0, isConst);
return &(state.back.vars[name].value);
}

long * arrayAddress (string name, long index)
long * arrayAddress (string name, long index, bool isConst = false)
{
foreach_reverse (ref cur; state)
{
Expand Down Expand Up @@ -306,17 +306,17 @@ class Runner
assert (false);
}

long * getAddr (VarExpression dest, bool canCreate)
long * getAddr (VarExpression dest, bool canCreate, bool isConst = false)
{
long * res;
if (dest.index is null)
{
res = varAddress (dest.name, canCreate);
res = varAddress (dest.name, canCreate, isConst);
}
else
{
auto indexValue = evalExpression (dest.index);
res = arrayAddress (dest.name, indexValue);
res = arrayAddress (dest.name, indexValue, isConst);
}
return res;
}
Expand Down Expand Up @@ -372,7 +372,7 @@ class Runner
return;
}

auto addr = getAddr (cur.dest, true);
auto addr = getAddr (cur.dest, true, cur.isConst);

auto value = control.queues[otherId][id].pop ();
doAssign (cur, addr, value);
Expand Down Expand Up @@ -409,11 +409,17 @@ class Runner
{
if (cur.dest.name in curState.arrays)
{
if(cur.isConst)
throw new Exception
("array: array cannot be const");
curState.arrays[cur.dest.name] =
Array (new long [values[0].to !(size_t)]);
return;
}
}
if(cur.isConst)
throw new Exception
("array: array cannot be const");
state.back.arrays[cur.dest.name] =
Array (new long [values[0].to !(size_t)]);
}
Expand All @@ -438,8 +444,37 @@ class Runner
return;
}

if(isConst && type == Type.assign)
{
auto varExpr = cast(VarExpression)(expr);
if (varExpr !is null && varExpr.name == dest.name && varExpr.index is null)
{
throw new Exception
("cannot initialize const " ~ dest.name ~" with itself");
}
}

auto value = evalExpression (expr);
auto addr = getAddr (dest, type == Type.assign);
auto addr = getAddr (dest, type == Type.assign, isConst);



if(isConst && type == Type.assign)
{
auto varExpr = cast(VarExpression)(expr);
foreach_reverse(ref curState; state)
{

if(dest.name in curState.vars)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Хмм, то есть мы можем сделать переменную константой в середине работы программы? Это странно, и выглядит скорее как баг, чем как фича...

В принципе я видел такую идиому в Rust. Но здесь, считаю, гораздо вероятнее, что программист ошибся и хотел создать новую константу во внутреннем контексте, чем что он хотел сделать константой существующую переменную.

{
if(dest.name in curState.vars && !curState.vars[dest.name].isConst)
throw new Exception
("refidinition of var " ~ dest.name ~ " to const");
curState.vars[dest.name].isConst = true;
break;
}
}
}
doAssign (cur0, addr, value);
delay = complexity;
return;
Expand Down
5 changes: 5 additions & 0 deletions syntax.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ function <name> ( <parameter-list> ) : \n <statement-list>
<while-block>
<for-block>
<if-block>
<const-decl>

<const-decl> is
const <name> = <expression0>

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ну как минимум это точно неправда =) в языке всё ещё нет оператора =


<assignment> is

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Мы же обсуждали изменение вида

<assignment> is
<variable> <assign-op> <expression0>
+const <variable> <assign-op> <expression0>

Соответственно, тогда понятно, что в parser.d меняется одна функция: parseAssignStatement.
Сейчас в коде так и есть, а в грамматике какой-то дебош вместо этого =)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Честно говоря, я не особо понимаю как работать с подобной грамматикой

<variable> <assign-op> <expression0>
Expand Down Expand Up @@ -93,6 +97,7 @@ function <name> ( <parameter-list> ) : \n <statement-list>
<constant>
<call>
( <expression0> )
<name>

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

неправда, мы <name> разбираем внутри <variable>


<constant> is
[0-9][0-9|_]*
Expand Down