For my Random Art application I have it where you can supply a file or read from standard input to enter an equation.
Let's says that we have this equation:
(mod (well (sin 0.323832 2.2861 (sin 2.21416 2.20967 (well (tent (mod (tent (well (level -0.0752852 (sin 2.31038 4.04912 (level 0.393861 (var y) (sin 2.27175 2.74322 (tent (mul (mul (const 1.0 0.2498657518497733 -0.4508747742435486 -0.7817632956531484) (var y)) (const 1.0 0.7058177970873616 0.05648855350264759 0.1956390702862447)))) (mod (var y) (var y)))) (mul (well (well (mul (const 1.0 -0.262451783952526 -0.9557663143478758 -0.3177802144623088) (level 0.873646 (var y) (tent (const 1.0 0.8737597600654188 0.2145221319526205 -0.8800570409541431)) (const 1.0 -0.9050919659388446 0.7983030361316761 -0.7426300942069357))))) (mix (tent (mix (mix (mul (const 1.0 0.0005090153890199289 0.8963316396858123 0.2295076731959949) (well (const 1.0 -0.17294630565278 -0.2597814845415081 -0.8611438063730192))) (tent (var y)) (mix (var x) (var x) (var x))) (var y) (mul (var y) (const 1.0 0.1984949013988651 -0.149133048456779 0.900995379685074)))) (const 1.0 -0.572116568903358 -0.582425320118741 0.9221462633860118) (const 1.0 0.8515710448950156 0.09543110744867755 0.6953341319171877))) (mod (level 0.119972 (var y) (const 1.0 0.5644823585304963 -0.240816323074402 0.009780741803530724) (const 1.0 0.5941273095148292 0.9028866229978196 -0.7522623294363084)) (level -0.280906 (level -0.938484 (var y) (var y) (const 1.0 -0.8330008122645283 -0.39239235774795 0.9457637360098534)) (tent (sin 0.857857 4.81552 (var x))) (well (level -0.852025 (well (const 1.0 -0.9067722398317444 0.2175722008405963 0.09878624628823118)) (mod (const 1.0 0.1045037796357171 0.7762375958354291 -0.2543003515749063) (var y)) (var y)))))))) (tent (mod (mul (sin 1.99553 3.2116 (level -0.530075 (const 1.0 -0.4779911452668899 0.7341569671124102 -0.4355799223886541) (const 1.0 -0.9953080041025508 0.5589681755988254 -0.9814996481022393) (mul (sum (mod (const 1.0 -0.8531852203948822 0.6996919272702189 -0.6039571136467909) (sin 2.65602 3.85619 (const 1.0 -0.7011700866243662 0.3411431002353571 -0.9922205275567477))) (well (well (sin 1.63543 1.14958 (mod (const 1.0 -0.4958935614895994 -0.9438318080507266 -0.3408021608995924) (tent (level 0.274502 (var y) (const 1.0 -0.4795642416292747 0.5876259287844712 0.3484844399742966) (well (const 1.0 0.5419683106764515 -0.7946591589812848 0.07410650283285314))))))))) (well (sum (tent (level 0.317093 (var x) (tent (tent (var y))) (const 1.0 -0.2457866764502814 0.7797848676144934 0.1643151126985445))) (var x)))))) (mix (const 1.0 -0.499152744198728 -0.1390031650603358 -0.8529944735698951) (well (sum (mix (const 1.0 0.0780918276008209 0.6131626116373732 0.6718962807749049) (const 1.0 -0.9064851547936681 0.5652453308583074 0.04537402571767579) (const 1.0 0.836942283646487 -0.1028272213030066 -0.8240229861473574)) (var x))) (mod (mix (const 1.0 -0.7404545633207191 -0.6246921536845007 -0.06576531058113844) (var y) (var x)) (var x)))) (mul (mix (const 1.0 0.625382878871366 -0.6791524432684528 0.7521549933168505) (tent (mix (mod (var x) (const 1.0 -0.3277935718962648 -0.7982178703500047 0.01108757040539965)) (mod (const 1.0 0.3653587675127565 0.8030702126603741 -0.4107967139394342) (sin 3.04352 3.42386 (var x))) (mix (const 1.0 0.05946871623260952 0.4367650102577687 0.6226078106956328) (const 1.0 0.6477246481977859 0.5779088008028843 0.2371171953464986) (well (well (mul (well (var x)) (level 0.187523 (var x) (const 1.0 0.1455087125923931 -0.5034719786445954 -0.3713323582418506) (const 1.0 0.06550490040596602 0.9570667786803981 -0.7493056578761825)))))))) (tent (mul (sin 2.28686 1.70396 (var x)) (mix (var x) (const 1.0 -0.7740499135025019 -0.794422918438054 -0.2092468221610879) (const 1.0 0.09454736418495679 0.6300192761406698 0.7957670065419316))))) (mix (var x) (mix (const 1.0 0.4589554458887553 0.5386799156605506 -0.5047090469217057) (mix (sin 1.1191 2.22732 (sum (var y) (const 1.0 0.2182635169546967 0.5921867609010918 -0.543125476636956))) (const 1.0 0.4174735562403922 0.2037691390567939 -0.09722367363269235) (var y)) (sin 2.45383 1.21389 (mix (const 1.0 -0.7701271648333892 0.09691024390769565 -0.3505571149163997) (sum (var y) (tent (sum (const 1.0 -0.1714863839884644 0.9640273910219537 0.1912242387230103) (mix (var x) (var x) (var x))))) (mul (const 1.0 -0.3084621050038328 0.2099181343666663 -0.9964771718495484) (tent (mul (var y) (const 1.0 -0.7745525399034272 0.0887411094311088 0.7798340505015406))))))) (const 1.0 0.8361986293672508 0.2862415088408707 -0.06633489220361444))))))))))) (mul (well (mod (const 1.0 0.5814648710477881 0.6797646798951895 -0.4038423943884637) (const 1.0 -0.4876464110789756 0.08098413875127397 -0.967264065568648))) (mul (level 0.760107 (tent (var x)) (well (const 1.0 0.9470297714685199 0.8125460041787296 -0.1953586753542713)) (const 1.0 -0.1388469768843792 0.6167734275732473 0.960828235961416)) (const 1.0 -0.9164760065790394 -0.4497486261799439 0.383871986459619))))
If I input it via a file or using a pipe (for stdin) it goes fine and renders the output. E.g.
./random_art eq.txt
or
./random_art stdin < eq.txt
But If I try and pasting the equation in the terminal (via stdin) I get errors and the program crashes. What might be causing this? It only seems to happen for very large equations like the one above. It doesn't happen for much smaller ones.
When I ran a debug build, I got this stack of errors:
Traceback (most recent call last)
random_art.nim(185) random_art
equationParser.nim(51) parseEquation
equationParser.nim(73) buildEquation
ModExpr.nim(72) buildMod
equationParser.nim(75) buildEquation
WellExpr.nim(56) buildWell
equationParser.nim(79) buildEquation
SinExpr.nim(84) buildSin
equationParser.nim(79) buildEquation
SinExpr.nim(84) buildSin
equationParser.nim(75) buildEquation
WellExpr.nim(56) buildWell
equationParser.nim(77) buildEquation
TentExpr.nim(57) buildTent
equationParser.nim(73) buildEquation
ModExpr.nim(73) buildMod
equationParser.nim(77) buildEquation
TentExpr.nim(57) buildTent
equationParser.nim(73) buildEquation
ModExpr.nim(73) buildMod
equationParser.nim(71) buildEquation
ProductExpr.nim(59) buildProduct
equationParser.nim(83) buildEquation
MixExpr.nim(63) buildMix
equationParser.nim(83) buildEquation
MixExpr.nim(64) buildMix
equationParser.nim(79) buildEquation
SinExpr.nim(84) buildSin
equationParser.nim(83) buildEquation
MixExpr.nim(63) buildMix
equationParser.nim(69) buildEquation
SumExpr.nim(62) buildSum
equationParser.nim(77) buildEquation
TentExpr.nim(57) buildTent
equationParser.nim(69) buildEquation
SumExpr.nim(61) buildSum
equationParser.nim(67) buildEquation
ConstExpr.nim(88) buildConst
strutils.nim parseFloat
Error: unhandled exception: invalid float: - [ValueError]
But I need to reiterate, it only happens when I copy and paste into a terminal using standard input. If it's piped in, there is no error what soever and renders fine.
I think it's running into a problem when the line length is greater than BufSize - in your example above, the equation is a little > 4000 chars long, and readAllBuffer is ultimately what's called.
I don't see obvious bugs, but I'm getting weird output for a test program:
let buf = readAll(stdin)
stdout.write(buf)
with pasting in your sample program as input when running ^^^ manually. I'll check again this weekend - if I can find the issue I'll make a PR, if not I"ll create an issue on the Github.
I think you're right - this is not a bug with Nim, but something to do with the buffer size for STDIN. You could try wrapping setvbuf and setting options on STDIN buffer size that way? maybe?
I get the same behavior with the Python script
from sys import stdin, stdout
input_eqn = stdin.read()
stdout.write(input_eqn)
giving weird results if I copy-paste directly (and working correctly if I cat the input from a file and pipe it to the script).