Skip to content

Commit be233ac

Browse files
committed
Add clearOutput() function
1 parent 99fbaa6 commit be233ac

19 files changed

+71
-18
lines changed

FlowRun_Exprs_Grammar.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
GRAMMAR:
3-
```ebnf
3+
```
44
expression -> boolOrComparison ("||" boolOrComparison)* ;
55
boolOrComparison -> boolAndComparison ("&&" boolAndComparison)* ;
66
boolAndComparison -> numComparison (("!=" | "==" ) numComparison)* ;
@@ -9,7 +9,12 @@ term -> factor (("+" | "-") factor)* ;
99
factor -> unary (("*" | "/" | "%") unary)* ;
1010
unary -> ("!" | "-") unary
1111
| atom ;
12-
atom -> NUMBER | STRING | "true" | "false"
12+
atom -> NUMBER
13+
| STRING
14+
| "true"
15+
| "false"
16+
| ID[intExpression]
17+
| ID[intExpression][intExpression]
1318
| ID
1419
| ID "(" expression? ( "," expression)* ")"
1520
| "(" expression ")" ;

TODO.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55
##
66

77

8-
- fix step-by-step on loops
98

109
- trim long text with ...
11-
- disable zoom config
10+
1211

1312

editor/src/main/scala/dev/sacode/flowrun/FlowRunEditor.scala

+2
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ class FlowRunEditor(
229229
flowchartPresenter.highlightExecuting(interpreter.nextExecStatementId)
230230
functionSelector.loadFunctions()
231231
flowchartPresenter.loadCurrentFunction()
232+
case ClearOutput() =>
233+
outputArea.clearRuntime()
232234
case SymbolTableUpdated =>
233235
debugArea.showVariables()
234236
case FunctionUpdated =>

interpreter/shared/src/main/scala/dev/sacode/flowrun/FlowRun.scala

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ object FlowRun:
1010
case EvalError(nodeId: String, msg: String, funId: String)
1111
case EvalOutput(msg: String, newline: Boolean)
1212
case EvalInput(nodeId: String, name: String, prompt: Option[String])
13+
case ClearOutput()
1314
case EvalFunctionStarted
1415
case EvalFunctionFinished
1516
case SyntaxSuccess

interpreter/shared/src/main/scala/dev/sacode/flowrun/ast/PredefinedFunction.scala

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ enum PredefinedFunction(val name: String) {
3131
case StringToInteger extends PredefinedFunction("string2int")
3232
// misc
3333
case ReadInput extends PredefinedFunction("readInput")
34+
case ClearOutput extends PredefinedFunction("clearOutput")
3435
}
3536

3637
object PredefinedFunction:

interpreter/shared/src/main/scala/dev/sacode/flowrun/codegen/CGenerator.scala

+1
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ class CGenerator(val programAst: Program) extends CodeGenerator {
252252
case RealToInteger => s"(int)${argOpt(0)}"
253253
case StringToInteger => s"atoi(${argOpt(0)})"
254254
case ReadInput => s"""scanf("%s", ${argOpt(0)})"""
255+
case ClearOutput => "printf(\"\\e[1;1H\\e[2J\")"
255256
case NumRows => s"sizeof(${argOpt(0)}) / sizeof(${argOpt(0)}[0])"
256257
case NumCols =>
257258
val arr = argOpt(0)

interpreter/shared/src/main/scala/dev/sacode/flowrun/codegen/CPlusPlusGenerator.scala

+1
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ class CPlusPlusGenerator(val programAst: Program) extends CodeGenerator {
247247
case RealToInteger => s"(int)${argOpt(0)}"
248248
case StringToInteger => s"atoi(${argOpt(0)})"
249249
case ReadInput => s"""scanf("%s", ${argOpt(0)})"""
250+
case ClearOutput => "printf(\"\\e[1;1H\\e[2J\")"
250251
case NumRows => s"sizeof(${argOpt(0)}) / sizeof(${argOpt(0)}[0])"
251252
case NumCols =>
252253
val arr = argOpt(0)

interpreter/shared/src/main/scala/dev/sacode/flowrun/codegen/CSharpGenerator.scala

+1
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ class CSharpGenerator(val programAst: Program) extends CodeGenerator {
210210
case RealToInteger => s"(int)${argOpt(0)}"
211211
case StringToInteger => s"Convert.ToInt32(${argOpt(0)})"
212212
case ReadInput => "Console.ReadLine()"
213+
case ClearOutput => "Console.Clear()"
213214
case NumRows => s"${argOpt(0)}.GetLength(0)"
214215
case NumCols => s"${argOpt(0)}.GetLength(1)"
215216
}

interpreter/shared/src/main/scala/dev/sacode/flowrun/codegen/JavaGenerator.scala

+4-2
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,10 @@ class JavaGenerator(val programAst: Program) extends CodeGenerator {
220220
case RealToInteger => s"(int)${argOpt(0)}"
221221
case StringToInteger => s"""Integer.parseInt(${argOpt(0)})"""
222222
case ReadInput => "scanner.nextLine()"
223-
case NumRows => s"${argOpt(0)}.length"
224-
case NumCols => s"${argOpt(0)}[0].length"
223+
case ClearOutput => """|System.out.print("\u001b[H\u001b[2J");
224+
|System.out.flush();""".stripMargin
225+
case NumRows => s"${argOpt(0)}.length"
226+
case NumCols => s"${argOpt(0)}[0].length"
225227
}
226228
}
227229

interpreter/shared/src/main/scala/dev/sacode/flowrun/codegen/JavascriptGenerator.scala

+1
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ class JavascriptGenerator(val programAst: Program) extends CodeGenerator {
181181
case RealToInteger => argOpt(0) // ??
182182
case StringToInteger => s"parseInt(${argOpt(0)})"
183183
case ReadInput => "prompt()"
184+
case ClearOutput => "console.clear()"
184185
case NumRows => s"${argOpt(0)}.length"
185186
case NumCols => s"${argOpt(0)}[0].length"
186187
}

interpreter/shared/src/main/scala/dev/sacode/flowrun/codegen/KotlinGenerator.scala

+4-3
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,10 @@ class KotlinGenerator(val programAst: Program) extends CodeGenerator {
198198
case RealToInteger => s"(int)${argOpt(0)}"
199199
case StringToInteger =>
200200
s"""try { Integer.parseInt(${argOpt(0)}) } catch (NumberFormatException e) { 0 }"""
201-
case ReadInput => "readLine()"
202-
case NumRows => s"${argOpt(0)}.size"
203-
case NumCols => s"${argOpt(0)}(1).size"
201+
case ReadInput => "readLine()"
202+
case ClearOutput => """print("\u001b[H\u001b[2J")"""
203+
case NumRows => s"${argOpt(0)}.size"
204+
case NumCols => s"${argOpt(0)}(1).size"
204205
}
205206
}
206207

interpreter/shared/src/main/scala/dev/sacode/flowrun/codegen/Language.scala

+1-3
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@ enum Language(val name: String, val prism: String):
1919
// unknown
2020
//case rust extends Language("rust", "rust")
2121

22+
// issues: async input handling
2223
//case nodejs extends Language("nodejs", "javascript")
2324

2425
// complex? variable declarations
2526
// case pascal extends Language("pascal", "pascal")
26-
27-
// complex string handling..
28-
// case c extends Language("c", "c")

interpreter/shared/src/main/scala/dev/sacode/flowrun/codegen/NodeJsGenerator.scala

+33-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import dev.sacode.flowrun.eval.SymbolTable
88
import dev.sacode.flowrun.eval.SymbolKey
99
import dev.sacode.flowrun.eval.Symbol
1010

11-
class NodeJsGenerator(override val programAst: Program) extends JavascriptGenerator(programAst) {
11+
class NodeJsGenerator(override val programAst: Program) extends CodeGenerator {
1212

1313
override def generate: Try[CodeGenRes] = Try {
1414

@@ -166,4 +166,36 @@ class NodeJsGenerator(override val programAst: Program) extends JavascriptGenera
166166
case Type.Boolean => "line"
167167
case _ => "line"
168168

169+
import PredefinedFunction.*
170+
171+
override def predefFun(name: String, genArgs: List[String]): String = {
172+
def argOpt(idx: Int) = genArgs.lift(idx).getOrElse("")
173+
174+
PredefinedFunction.withName(name).get match {
175+
case Abs => s"Math.abs(${argOpt(0)})"
176+
case Floor => s"Math.floor(${argOpt(0)})"
177+
case Ceil => s"Math.ceil(${argOpt(0)})"
178+
case RandomInteger => s"Math.floor(Math.random()*${argOpt(0)})"
179+
case Sin => s"Math.sin(${argOpt(0)})"
180+
case Cos => s"Math.cos(${argOpt(0)})"
181+
case Tan => s"Math.tan(${argOpt(0)})"
182+
case Ln => s"Math.log(${argOpt(0)})"
183+
case Log10 => s"Math.log10(${argOpt(0)})"
184+
case Log2 => s"Math.log2(${argOpt(0)})"
185+
case Sqrt => s"Math.sqrt(${argOpt(0)})"
186+
case Pow => s"Math.pow(${argOpt(0)}, ${argOpt(1)})"
187+
case Length => s"${argOpt(0)}.length"
188+
case CharAt => s"${argOpt(0)}.charAt(${argOpt(1)})"
189+
case RealToInteger => argOpt(0) // ??
190+
case StringToInteger => s"parseInt(${argOpt(0)})"
191+
case ReadInput => "line"
192+
case ClearOutput => "process.stdout.write('\\x1Bc')"
193+
case NumRows => s"${argOpt(0)}.length"
194+
case NumCols => s"${argOpt(0)}[0].length"
195+
}
196+
}
197+
198+
override def funCall(name: String, genArgs: List[String]): String =
199+
s""" $name(${genArgs.mkString(", ")}) """.trim
200+
169201
}

interpreter/shared/src/main/scala/dev/sacode/flowrun/codegen/PhpGenerator.scala

+1
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ class PhpGenerator(val programAst: Program) extends CodeGenerator {
156156
case RealToInteger => argOpt(0)
157157
case StringToInteger => s""" intval(${argOpt(0)}) """.trim
158158
case ReadInput => "readline()"
159+
case ClearOutput => s""" echo chr(27).chr(91).'H'.chr(27).chr(91).'J'; """
159160
case NumRows => s"count(${argOpt(0)})"
160161
case NumCols => s"count(${argOpt(0)}[0])"
161162
}

interpreter/shared/src/main/scala/dev/sacode/flowrun/codegen/PythonGenerator.scala

+3-2
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ class PythonGenerator(val programAst: Program) extends CodeGenerator {
2121
}
2222

2323
def generate: Try[CodeGenRes] = Try {
24-
// TODO optionally import
2524
addLine("import math", "")
26-
addLine("from random import randrange", "")
25+
val usesRandom = programAst.usesFunction(PredefinedFunction.RandomInteger)
26+
if usesRandom then addLine("from random import randrange", "")
2727

2828
programAst.functions.foreach(genFunction)
2929
addEmptyLine()
@@ -198,6 +198,7 @@ class PythonGenerator(val programAst: Program) extends CodeGenerator {
198198
case RealToInteger => s"int(${argOpt(0)})"
199199
case StringToInteger => s"int(${argOpt(0)})"
200200
case ReadInput => "input()"
201+
case ClearOutput => """ print("\033[H\033[J", end="") """.trim
201202
case NumRows => s"len(${argOpt(0)})"
202203
case NumCols => s"len(${argOpt(0)}[0])"
203204
}

interpreter/shared/src/main/scala/dev/sacode/flowrun/codegen/RubyGenerator.scala

+1
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ class RubyGenerator(val programAst: Program) extends CodeGenerator {
196196
case RealToInteger => s"${argOpt(0)}.toInt"
197197
case StringToInteger => s"${argOpt(0)}.to_i"
198198
case ReadInput => "$stdin.read"
199+
case ClearOutput => s""" system "clear" || system "cls" """
199200
case NumRows => s"${argOpt(0)}.length"
200201
case NumCols => s"${argOpt(0)}[0].length"
201202
}

interpreter/shared/src/main/scala/dev/sacode/flowrun/codegen/ScalaGenerator.scala

+1
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ class ScalaGenerator(val programAst: Program) extends CodeGenerator {
212212
case RealToInteger => s"${argOpt(0)}.toInt"
213213
case StringToInteger => s"${argOpt(0)}.toInt"
214214
case ReadInput => "StdIn.readLine()"
215+
case ClearOutput => """print("\u001b[H\u001b[2J")"""
215216
case NumRows => s"${argOpt(0)}.length"
216217
case NumCols => s"${argOpt(0)}(0).length"
217218
}

interpreter/shared/src/main/scala/dev/sacode/flowrun/codegen/SwiftGenerator.scala

+4-3
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,10 @@ class SwiftGenerator(val programAst: Program) extends CodeGenerator {
187187
s"""try Int(${argOpt(0)})! catch {
188188
| case _: NumberFormatException => 0
189189
|}""".stripMargin
190-
case ReadInput => "readLine()!"
191-
case NumRows => s"${argOpt(0)}.count"
192-
case NumCols => s"${argOpt(0)}[0].count"
190+
case ReadInput => "readLine()!"
191+
case ClearOutput => """print("\u{001B}[2J")"""
192+
case NumRows => s"${argOpt(0)}.count"
193+
case NumCols => s"${argOpt(0)}[0].count"
193194
}
194195
}
195196

interpreter/shared/src/main/scala/dev/sacode/flowrun/eval/Interpreter.scala

+3
Original file line numberDiff line numberDiff line change
@@ -1377,6 +1377,9 @@ final class Interpreter(
13771377
waitForContinue().map(_ =>
13781378
lastReadInput.getOrElse(throw EvalException(s"readInput() did not get any input", id))
13791379
)
1380+
case ClearOutput =>
1381+
flowrunChannel := FlowRun.Event.ClearOutput()
1382+
Future.successful(NoVal)
13801383
}
13811384

13821385
private def validateArgsNumber(id: String, funName: String, expected: Int, got: Int): Unit =

0 commit comments

Comments
 (0)