Long code line continuation method in GAP language - gap-system

Take the following code snippet as an example:
f:= FreeGroup("P","Q","R","S");
AssignGeneratorVariables(f);
g:= f/ParseRelators(f, "P^12=Q^4=R^4=S^8=1, Q^2=R^2, S^2 = P^6*Q^2*R,
Q*P=P^7*Q^2*R, Q*P^3=P^3*Q, R*P=P^10*Q*R, R*Q=P^6*Q^3*R, S*P=P^2*R*S,
S*Q=P^3*Q^3*R*S, S*R=R*S" );
I'm not sure if there is a long code line continuation method
implemented in GAP language.
Edit: Based on the nice tricks and tips given by Olexandr and Horn, I would like to add some corresponding supplementary information as follows:
"Triple Quoted Strings" is described here.
The handling mechanism of line continuation, i.e., backslash followed by new line, is described here.
In addition, the gap source code also includes the following description:
$ ugrep -i 'line continuation.*backslash'
bin/x86_64-pc-linux-gnu-default64-kv8/src/io.c: // handle line continuation, i.e., backslash followed by new line; and
src/io.c: // handle line continuation, i.e., backslash followed by new line; and
Regards,
HZ

The problem here is not with the command occupying several lines, but with the string including a line break, as the error message says:
gap> g:= f/ParseRelators(f, "P^12=Q^4=R^4=S^8=1, Q^2=R^2, S^2 = P^6*Q^2*R,
Syntax error: String must not include <newline>
g:= f/ParseRelators(f, "P^12=Q^4=R^4=S^8=1, Q^2=R^2, S^2 = P^6*Q^2*R,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You have to use backslash \ to continue the string from a new line. This input works:
f:= FreeGroup("P","Q","R","S");
AssignGeneratorVariables(f);
g:= f/ParseRelators(f, "P^12=Q^4=R^4=S^8=1, Q^2=R^2, S^2 = P^6*Q^2*R,\
Q*P=P^7*Q^2*R, Q*P^3=P^3*Q, R*P=P^10*Q*R, R*Q=P^6*Q^3*R, S*P=P^2*R*S,\
S*Q=P^3*Q^3*R*S, S*R=R*S" );
You can also use spaces as you like to indent and format it, e.g.
f:= FreeGroup("P","Q","R","S");
AssignGeneratorVariables(f);
g:= f/ParseRelators(f,
"P^12 = Q^4 = R^4 = S^8 = 1, \
Q^2 = R^2, S^2 = P^6*Q^2*R, \
Q*P = P^7*Q^2*R, \
Q*P^3 = P^3*Q, \
R*P = P^10*Q*R, \
R*Q = P^6*Q^3*R, \
S*P = P^2*R*S, \
S*Q = P^3*Q^3*R*S, \
S*R = R*S" );
or so.

As an alternative to the nice answer by Olexandr, let me mention that you can also use triple quoted strings to avoid the need for line continuations. E.g. like this:
f:= FreeGroup("P","Q","R","S");
AssignGeneratorVariables(f);
g:= f/ParseRelators(f, """
P^12 = Q^4 = R^4 = S^8 = 1,
Q^2 = R^2, S^2 = P^6*Q^2*R,
Q*P = P^7*Q^2*R,
Q*P^3 = P^3*Q,
R*P = P^10*Q*R,
R*Q = P^6*Q^3*R,
S*P = P^2*R*S,
S*Q = P^3*Q^3*R*S,
S*R = R*S
""" );

Related

Nextflow adding def function in to script

I have got errors like .command.sh: line 2: syntax error near unexpected token `('
/*
* Step 3
*/
chr_length = file(params.chr_length)
process create_bedgraph_and_bigwig {
publishDir "${params.outdir}/bedgraphandbigwig", mode: 'copy'
input:
set val(sample_id), file(vector_log) from vector_log_ch
set val(sample_id), file(target_query_bam) from target_query_bam_ch
file chr_length
output:
set val(sample_id), file("${sample_id}.bedgraph.log.txt") into bed_log_ch
set val(sample_id), file("${sample_id}.bed") into bed_ch
set val(sample_id), file("${sample_id}.clean.bed") into clean_bed_ch
set val(sample_id), file("${sample_id}.fragments.bed") into fragments_bed_ch
set val(sample_id), file("${sample_id}.sorted.fragments.bed") into sorted_fragments_bed_ch
shell:
'''
def fp = file(${vector_log})
def lines = fp.readLines()
def line3 = lines[3].split(' ')[4].toInteger()
def line4 = lines[4].split(' ')[4].toInteger()
def aln_sum = (10000/(line3 + line4)).toString()
bedtools bamtobed -bedpe -i !{target_query_bam} > !{sample_id}.bed 2>!{sample_id}.bedgraph.log.txt
awk '$1==$4 && $6-$2 < 1000 {{print $0}}' !{sample_id}.bed > !{sample_id}.clean.bed 2>!{sample_id}.bedgraph.log.txt
cut -f 1,2,6 !{sample_id}.clean.bed > !{sample_id}.fragments.bed 2>!{sample_id}.bedgraph.log.txt
sort -k 1,1 !{sample_id}.fragments.bed > !{sample_id}.sorted.fragments.bed
'''
}
The simple answer is to avoid using 'def' if the variable needs to be used in a shell definition or template. I couldn't actually find this after a quick search of the documentation, but I did find this note from the author:
Using groovy native string interpolation that would work, but when using the !{..} syntax scripts variable cannot be declared locally using the def keyword.
To summarise:
script/shell variable should be defensively declared in the local scope using the def keyboard
do not use def when:
i. the variable needs to be referenced as a output value
ii. the variable needs to be used in a shell template
https://github.com/nextflow-io/nextflow/issues/678#issuecomment-386206123

Changes in lua language cause error in ai script

When I run script in game, I got an error message like this:
.\AI\haick.lua:104: bad argument #1 to 'find' (string expected, got nill)
local haick = {}
haick.type = type
haick.tostring = tostring
haick.require = require
haick.error = error
haick.getmetatable = getmetatable
haick.setmetatable = setmetatable
haick.ipairs = ipairs
haick.rawset = rawset
haick.pcall = pcall
haick.len = string.len
haick.sub = string.sub
haick.find = string.find
haick.seed = math.randomseed
haick.max = math.max
haick.abs = math.abs
haick.open = io.open
haick.rename = os.rename
haick.remove = os.remove
haick.date = os.date
haick.exit = os.exit
haick.time = GetTick
haick.actors = GetActors
haick.var = GetV
--> General > Seeding Random:
haick.seed(haick.time())
--> General > Finding Script Location:
local scriptLocation = haick.sub(_REQUIREDNAME, 1, haick.find(_REQUIREDNAME,'/[^\/:*?"<>|]+$'))
Last line (104 in file) causes error and I don`t know how to fix it.
There are links to .lua files below:
https://drive.google.com/file/d/1F90v-h4VjDb0rZUCUETY9684PPGw7IVG/view?usp=sharing
https://drive.google.com/file/d/1fi_wmM3rg7Ov33yM1uo7F_7b-bMPI-Ye/view?usp=sharing
Help, pls!
When you use a function in Lua, you are expected to pass valid arguments for the function.
To use a variable, you must first define it, _REQUIREDNAME in this case is not available, haick.lua file is incomplete. The fault is of the author of the file.
Lua has a very useful reference you can use if you need help, see here

first `readLine` is skipped inside a `case - of` control flow in Nim-lang

I have the following code.
import lib
var stat = false
when isMainModule:
while stat != true:
echo("Option: ")
var opt = readChar(stdin)
case opt
of 'q':
stat = true
of 'n':
echo("Salu: ")
var ss = readLine(stdin)
echo("Nam: ")
var nn = readLine(stdin)
let k = prompt("Rust")
else: discard
What I am trying to achieve is, prompting and receiving user input one after another for two variables. Upon choosing n I am expecting Salu first and once user input is supplied then Nam.
However, what I receive when I execute the following nim code by issuing the following command is, nim c -r src/mycode.nim
~~> nim c -r src/cmdparsing.nim
...
...
...
CC: stdlib_system.nim
CC: cmdparsing.nim
Hint: [Link]
Hint: operation successful (48441 lines compiled; 2.338 sec total; 66.824MiB peakmem; Debug Build) [SuccessX]
Hint: /home/XXXXX/Development/nim_devel/mycode/src/mycode [Exec]
Option:
n
Salu:
Nam:
Salu is being echoed, but readLine doesn't wait for my input and immediately echoes Nam. But, stacked readLine commands from the prompt procedure appears one after the other for receiving user input.
I was wondering what is that I am missing to understand here. Could someone enlighten me?
Code for prompt lives in lib.nim which is as follows,
proc prompt*(name: string): bool =
echo("Salutation: ")
var nn = readLine(stdin)
echo(nn&"."&name)
echo("Diesel")
var dd = readLine(stdin)
echo(dd)
return true
You do a readChar to get the opt value, and then you input two chars: n and \n. The first is the opt value, the second gets buffered or retained in the stdin waiting for further reading. The next time you try to read a line, the \n that's still hanging is interpreted as a new line, and immediately assigned to ss. You don't see anything because the line is empty except for the newline char.
E.g.
var opt = readChar(stdin)
case opt
of 'n':
var ss = readLine(stdin)
echo ss
else:
discard
Compile and run, but in the input write something like "ntest". n fires the first branch of case, test (the remainder of stdin) is assigned to ss, and echoed.
You have two options to solve the problem:
Read a line instead of a char, and store only the first char with something like var opt = readLine(stdin)[0].
Use the rdstdin module:
import rdstdin
var ss = readLineFromStdin("Salu:")

How can I signal parsing errors with LPeg?

I'm writing an LPeg-based parser. How can I make it so a parsing error returns nil, errmsg?
I know I can use error(), but as far as I know that creates a normal error, not nil, errmsg.
The code is pretty long, but the relevant part is this:
local eof = lpeg.P(-1)
local nl = (lpeg.P "\r")^-1 * lpeg.P "\n" + lpeg.P "\\n" + eof -- \r for winblows compat
local nlnoeof = (lpeg.P "\r")^-1 * lpeg.P "\n" + lpeg.P "\\n"
local ws = lpeg.S(" \t")
local inlineComment = lpeg.P("`") * (1 - (lpeg.S("`") + nl * nl)) ^ 0 * lpeg.P("`")
local wsc = ws + inlineComment -- comments count as whitespace
local backslashEscaped
= lpeg.P("\\ ") / " " -- escaped spaces
+ lpeg.P("\\\\") / "\\" -- escaped escape character
+ lpeg.P("\\#") / "#"
+ lpeg.P("\\>") / ">"
+ lpeg.P("\\`") / "`"
+ lpeg.P("\\n") -- \\n newlines count as backslash escaped
+ lpeg.P("\\") * lpeg.P(function(_, i)
error("Unknown backslash escape at position " .. i) -- this error() is what I wanna get rid of.
end)
local Line = lpeg.C((wsc + (backslashEscaped + 1 - nl))^0) / function(x) return x end * nl * lpeg.Cp()
I want Line:match(...) to return nil, errmsg when there's an invalid escape.
LPeg itself doesn't provide specific functions to help you with error reporting. A quick fix to your problem would be to make a protected call (pcall) to match like this:
local function parse(text)
local ok, result = pcall(function () return Line:match(text) end)
if ok then
return result
else
-- `result` will contain the error thrown. If it is a string
-- Lua will add additional information to it (filename and line number).
-- If you do not want this, throw a table instead like `{ msg = "error" }`
-- and access the message using `result.msg`
return nil, result
end
end
However, this will also catch any other error, which you probably don't want. A better solution would be to use LPegLabel instead. LPegLabel is an extension of LPeg that adds support for labeled failures. Just replace require"lpeg" with require"lpeglabel" and then use lpeg.T(L) to throw labels where L is an integer from 1-255 (0 is used for regular PEG failures).
local unknown_escape = 1
local backslashEscaped = ... + lpeg.P("\\") * lpeg.T(unknown_escape)
Now Line:match(...) will return nil, label, suffix if there is a label thrown (suffix is the remaining unprocessed input, which you can use to compute for the error position via its length). With this, you can print out the appropriate error message based on the label. For more complex grammars, you would probably want a more systematic way of mapping the error labels and messages. Please check the documentation found in the readme of the LPegLabel repository to see examples of how one may do so.
LPegLabel also allows you to catch the labels in the grammar by the way (via labeled choice); this is useful for implementing things like error recovery. For more information on labeled failures and examples, please check the documentation.

User input after print

I'm trying to make a simple lua program that converts Fahrenheit to Celsius and kelvin and I don't know how to put an input command on the same line as a print line. Here's what I mean.
I want the program to display:
Fahrenheit = "Here's the user input"
I know how to make it say
Fahrenheit =
"User input"
I'm still a novice.
This is my code so far:
print("Fahrenheit = ") f = io.read() c = (5/9)*(f-32)
print("Celsius = "..c) k = c + 273 print("Kelvin = "..k)
Look into io.write() and io.read(). For instance, you could say:
io.write("Fahrenheit = ")
The write command writes output to the screen buffer, but doesn't add a newline. Similarly, read checks the latest input, and returns it.
For reference, I suggest this link from the tutorial.