From cd3d5672309e66cbf5eb3bee7c0cbaee2c7b7de6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=B0=D1=88=D0=B5=D0=BD=D0=B8=D0=BD=20=D0=90=D0=BD?= =?UTF-8?q?=D0=B4=D1=80=D0=B5=D0=B9?= Date: Sun, 6 Apr 2025 17:20:46 +0300 Subject: [PATCH 1/6] adding first logic for constant var --- source/language.d | 4 +++- source/parser.d | 11 +++++++++-- source/runner.d | 15 ++++++++++++++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/source/language.d b/source/language.d index d0bfe0e..7e96573 100644 --- a/source/language.d +++ b/source/language.d @@ -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_; } } diff --git a/source/parser.d b/source/parser.d index f1b8fb4..e4a6d3b 100644 --- a/source/parser.d +++ b/source/parser.d @@ -53,7 +53,7 @@ struct Line } while (!t.empty && (t.front.isDigit || t.front == '_')); } - else if (t.front.isIdent) + else if (t.front.isIdent || t == "const") { do { @@ -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"); @@ -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) diff --git a/source/runner.d b/source/runner.d index 19713d0..2c3814e 100644 --- a/source/runner.d +++ b/source/runner.d @@ -410,7 +410,7 @@ class Runner if (cur.dest.name in curState.arrays) { curState.arrays[cur.dest.name] = - Array (new long [values[0].to !(size_t)]); + Array (new long [values[0].to !(size_t)], cur.isConst); return; } } @@ -440,6 +440,19 @@ class Runner auto value = evalExpression (expr); auto addr = getAddr (dest, type == Type.assign); + + if(isConst && type == Type.assign) + { + foreach_reverse(ref curState; state) + { + if(dest.name in curState.vars) + { + curState.vars[dest.name].isConst = true; + break; + } + } + } + doAssign (cur0, addr, value); delay = complexity; return; From 8522612d69890728ed6354f578cb8a2bc5e352f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=B0=D1=88=D0=B5=D0=BD=D0=B8=D0=BD=20=D0=90=D0=BD?= =?UTF-8?q?=D0=B4=D1=80=D0=B5=D0=B9?= Date: Sun, 6 Apr 2025 17:43:05 +0300 Subject: [PATCH 2/6] added logic for const arrays --- source/runner.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/runner.d b/source/runner.d index 2c3814e..1947b0f 100644 --- a/source/runner.d +++ b/source/runner.d @@ -415,7 +415,7 @@ class Runner } } state.back.arrays[cur.dest.name] = - Array (new long [values[0].to !(size_t)]); + Array (new long [values[0].to !(size_t)], cur.isConst); } void runStatementImpl (Statement s) From d4fd8bb679c12e4e1fc5b43e095783566bdac3cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=B0=D1=88=D0=B5=D0=BD=D0=B8=D0=BD=20=D0=90=D0=BD?= =?UTF-8?q?=D0=B4=D1=80=D0=B5=D0=B9?= Date: Sun, 6 Apr 2025 18:53:57 +0300 Subject: [PATCH 3/6] fixed problems --- source/parser.d | 10 +++++++++- source/runner.d | 33 ++++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/source/parser.d b/source/parser.d index e4a6d3b..1d1dc51 100644 --- a/source/parser.d +++ b/source/parser.d @@ -53,7 +53,15 @@ struct Line } while (!t.empty && (t.front.isDigit || t.front == '_')); } - else if (t.front.isIdent || t == "const") + else if(t == "const"){ + do + { + temp ~= t.front; + t.popFront (); + } + while (!t.empty && t.front.isIdent); + } + else if (t.front.isIdent) { do { diff --git a/source/runner.d b/source/runner.d index 1947b0f..82fe4b7 100644 --- a/source/runner.d +++ b/source/runner.d @@ -409,13 +409,19 @@ 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)], cur.isConst); + 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)], cur.isConst); + Array (new long [values[0].to !(size_t)]); } void runStatementImpl (Statement s) @@ -438,21 +444,38 @@ 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); + + if(isConst && type == Type.assign) { foreach_reverse(ref curState; state) { if(dest.name in curState.vars) { - curState.vars[dest.name].isConst = true; - break; + if(dest.name in curState.vars) + { + if(!curState.vars[dest.name].isConst) + throw new Exception + ("redifinition of " ~ dest.name ~" variable to const"); + curState.vars[dest.name].isConst = true; + break; + } } } } - doAssign (cur0, addr, value); delay = complexity; return; From 8363bdba06f8148c2e021121685098c134ba9952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=B0=D1=88=D0=B5=D0=BD=D0=B8=D0=BD=20=D0=90=D0=BD?= =?UTF-8?q?=D0=B4=D1=80=D0=B5=D0=B9?= Date: Sun, 6 Apr 2025 19:39:38 +0300 Subject: [PATCH 4/6] refactored code and fixed previous bug --- source/parser.d | 8 -------- source/runner.d | 33 ++++++++++++++++----------------- syntax.txt | 5 +++++ 3 files changed, 21 insertions(+), 25 deletions(-) diff --git a/source/parser.d b/source/parser.d index 1d1dc51..a87c06f 100644 --- a/source/parser.d +++ b/source/parser.d @@ -53,14 +53,6 @@ struct Line } while (!t.empty && (t.front.isDigit || t.front == '_')); } - else if(t == "const"){ - do - { - temp ~= t.front; - t.popFront (); - } - while (!t.empty && t.front.isIdent); - } else if (t.front.isIdent) { do diff --git a/source/runner.d b/source/runner.d index 82fe4b7..ab5b44b 100644 --- a/source/runner.d +++ b/source/runner.d @@ -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) { @@ -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) { @@ -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; } @@ -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); @@ -446,7 +446,7 @@ class Runner if(isConst && type == Type.assign) { - auto varExpr = cast(VarExpression)(expr); + auto varExpr = cast(VarExpression)(expr); if (varExpr !is null && varExpr.name == dest.name && varExpr.index is null) { throw new Exception @@ -455,24 +455,23 @@ class Runner } 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) { - if(dest.name in curState.vars) - { - if(!curState.vars[dest.name].isConst) - throw new Exception - ("redifinition of " ~ dest.name ~" variable to const"); - curState.vars[dest.name].isConst = true; - break; - } + 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; } } } diff --git a/syntax.txt b/syntax.txt index 86e6414..5b51b34 100644 --- a/syntax.txt +++ b/syntax.txt @@ -18,6 +18,10 @@ function ( ) : \n + + + is +const = is @@ -93,6 +97,7 @@ function ( ) : \n ( ) + is [0-9][0-9|_]* From f959243416016c4804e318e92b93a364d0cf8c4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=B0=D1=88=D0=B5=D0=BD=D0=B8=D0=BD=20=D0=90=D0=BD?= =?UTF-8?q?=D0=B4=D1=80=D0=B5=D0=B9?= Date: Mon, 7 Apr 2025 13:54:37 +0300 Subject: [PATCH 5/6] tried to remake syntax.txt --- syntax.txt | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/syntax.txt b/syntax.txt index 5b51b34..1d2e90e 100644 --- a/syntax.txt +++ b/syntax.txt @@ -18,13 +18,10 @@ function ( ) : \n - - - is -const = is +const is @@ -97,7 +94,6 @@ const = ( ) - is [0-9][0-9|_]* @@ -125,4 +121,4 @@ if : \n \n is elif : \n elif : \n \n else \n -elif : \n \n +elif : \n \n \ No newline at end of file From 54ffb660143ccabcd98b47b64aeab2b3e4452e4d Mon Sep 17 00:00:00 2001 From: Andrey Kashenin Date: Fri, 26 Dec 2025 16:40:09 +0300 Subject: [PATCH 6/6] fixed test --- source/parser.d | 15 ++++++++++----- source/runner.d | 14 +++++++------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/source/parser.d b/source/parser.d index a87c06f..bca0785 100644 --- a/source/parser.d +++ b/source/parser.d @@ -499,16 +499,21 @@ 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(); - } + { + isConst = true; + line.tokens.popFront(); + } auto var = cast (VarExpression) (parseExpression (line)); check (var !is null, line, - "assign statement detected but left side not parsed"); + "assign statement detected but left side not parsed"); + if (isConst && var.index !is null) + { + throw new Exception("cannot declare array element as constant"); + } check (!line.tokens.empty, line, "expected assignment operator, found end of line"); diff --git a/source/runner.d b/source/runner.d index ab5b44b..5cffedb 100644 --- a/source/runner.d +++ b/source/runner.d @@ -119,7 +119,7 @@ class Runner if (cur.vars[name].isConst) { throw new Exception ("variable " ~ name ~ - " is constant"); + " is constant"); } return &(cur.vars[name].value); } @@ -141,7 +141,7 @@ class Runner if (cur.arrays[name].isConst) { throw new Exception ("array " ~ name ~ - " is constant"); + " is constant"); } if (index < 0 || cur.arrays[name].contents.length <= index) @@ -411,7 +411,7 @@ class Runner { if(cur.isConst) throw new Exception - ("array: array cannot be const"); + ("array: array cannot be constant"); curState.arrays[cur.dest.name] = Array (new long [values[0].to !(size_t)]); return; @@ -419,7 +419,7 @@ class Runner } if(cur.isConst) throw new Exception - ("array: array cannot be const"); + ("array: array cannot be constant"); state.back.arrays[cur.dest.name] = Array (new long [values[0].to !(size_t)]); } @@ -449,8 +449,8 @@ class Runner 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"); + throw new Exception + ("cannot initialize constant " ~ dest.name ~ " with itself"); } } @@ -469,7 +469,7 @@ class Runner { if(dest.name in curState.vars && !curState.vars[dest.name].isConst) throw new Exception - ("refidinition of var " ~ dest.name ~ " to const"); + ("redefinition of variable " ~ dest.name ~ " as constant"); curState.vars[dest.name].isConst = true; break; }