Browse code

Add source code of the assembler compiler

Pawel Jablonski authored on 14/12/2022 19:04:16
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,743 @@
1
+/*
2
+ * Author: Pawel Jablonski
3
+ * E-mail: pj@xirx.net
4
+ * WWW: xirx.net
5
+ * GIT: git.xirx.net
6
+ *
7
+ * License: You can use this code however you like
8
+ * but leave information about the original author.
9
+ * Code is free for non-commercial and commercial use.
10
+ */
11
+
12
+#include "compiler.h"
13
+
14
+/**
15
+ * Constructor of the compiler
16
+ *
17
+ * @param dataList Data list
18
+ */
19
+Compiler::Compiler(DataList &dataList) : dataList(dataList)
20
+{
21
+}
22
+
23
+/**
24
+ * Add an instruction to the uROM opcode table
25
+ *
26
+ * @param instruction Instruction to add
27
+ */
28
+void Compiler::addInstruction(const Instruction &instruction)
29
+{
30
+	this->instructionList.append(instruction);
31
+}
32
+
33
+/**
34
+ * Compile the application
35
+ *
36
+ * @return Status of compiling the application
37
+ */
38
+bool Compiler::compile()
39
+{
40
+	QTextStream out(stdout);
41
+
42
+	for(const QSharedPointer<Data> &data : this->dataList)
43
+	{
44
+		if(!(this->compileRam(*data)))
45
+		{
46
+			return(false);
47
+		}
48
+
49
+		if(!(this->compileFlash(*data)))
50
+		{
51
+			return(false);
52
+		}
53
+
54
+		if(!(this->compileCode(*data)))
55
+		{
56
+			return(false);
57
+		}
58
+	}
59
+
60
+	return(true);
61
+}
62
+
63
+/**
64
+ * Check the type of the param
65
+ *
66
+ * @param param String to check
67
+ *
68
+ * @return Param type
69
+ */
70
+QList<Instruction::Arg> Compiler::checkParamType(const QString &param)
71
+{
72
+	QList<Instruction::Arg> argList;
73
+
74
+	if(param.contains(QRegularExpression("^(a|b|x|y|A|B|X|Y)$")))
75
+	{
76
+		argList.append(Instruction::Arg::ABXY);
77
+
78
+		if(param.contains(QRegularExpression("^(a|b|A|B)$")))
79
+		{
80
+			argList.append(Instruction::Arg::AB);
81
+		}
82
+	}
83
+	else if(param.contains(QRegularExpression("^([0-9]+|0b[01]+|0x[0-9abcdefABCDEF]+|'.')$")))
84
+	{
85
+		argList.append(Instruction::Arg::Val256);
86
+
87
+		if(param.contains(QRegularExpression("^(0x[0-9abcdefABCDEF]+)$")))
88
+		{
89
+			argList.append(Instruction::Arg::Addr);
90
+		}
91
+	}
92
+	else if(param.contains(QRegularExpression(R"(^(\.[0-9a-zA-Z_-]+)$)")))
93
+	{
94
+		argList.append(Instruction::Arg::Addr);
95
+	}
96
+	else if(param.contains(QRegularExpression(R"(^(\*[0-9a-zA-Z_-]+)$)")))
97
+	{
98
+		argList.append(Instruction::Arg::Addr);
99
+	}
100
+	else if(param.contains(QRegularExpression(R"(^(\*[0-9a-zA-Z_-]+\[[0-9]+\])$)")))
101
+	{
102
+		argList.append(Instruction::Arg::Addr);
103
+	}
104
+	else if(param.contains(QRegularExpression(R"(^((low|high)\(\.[0-9a-zA-Z_-]+\))$)")))
105
+	{
106
+		argList.append(Instruction::Arg::Val256);
107
+	}
108
+	else if(param.contains(QRegularExpression(R"(^((low|high)\(\*[0-9a-zA-Z_-]+\))$)")))
109
+	{
110
+		argList.append(Instruction::Arg::Val256);
111
+	}
112
+	else if(param.contains(QRegularExpression(R"(^((low|high)\(\*[0-9a-zA-Z_-]+\[[0-9]+\]\))$)")))
113
+	{
114
+		argList.append(Instruction::Arg::Val256);
115
+	}
116
+
117
+	return(argList);
118
+}
119
+
120
+/**
121
+ * Compile the RAM items
122
+ *
123
+ * @param data Data of the parsed application
124
+ *
125
+ * @return Status of compiling the RAM items
126
+ */
127
+bool Compiler::compileRam(Data &data)
128
+{
129
+	QTextStream out(stdout);
130
+
131
+	for(const QSharedPointer<RamItem> &ramItem : data.getRamItemList())
132
+	{
133
+		bool compiled = false;
134
+		QString arraySize = ramItem->getArraySize();
135
+
136
+		if(arraySize.length() > 0)
137
+		{
138
+			if(arraySize.contains(QRegularExpression("^([0-9]+)$")))
139
+			{
140
+				bool isOk;
141
+				unsigned int size = arraySize.toUInt(&isOk, 10);
142
+
143
+				if(isOk)
144
+				{
145
+					ramItem->setDataSize(size);
146
+					compiled = true;
147
+				}
148
+			}
149
+		}
150
+		else
151
+		{
152
+			ramItem->setDataSize(1);
153
+			compiled = true;
154
+		}
155
+
156
+		if(!compiled)
157
+		{
158
+			out << QString("ERROR: Syntax error at line %1 in file: \"%2\"\n").arg(ramItem->getLine()).arg(data.getFileName());
159
+			return(false);
160
+		}
161
+	}
162
+
163
+	return(true);
164
+}
165
+
166
+/**
167
+ * Compile the Flash items
168
+ *
169
+ * @param data Data of the parsed application
170
+ *
171
+ * @return Status of compiling the Flash items
172
+ */
173
+bool Compiler::compileFlash(Data &data)
174
+{
175
+	QTextStream out(stdout);
176
+
177
+	for(const QSharedPointer<FlashItem> &flashItem : data.getFlashItemList())
178
+	{
179
+		bool compiled = true;
180
+		bool isString = false;
181
+
182
+		if(flashItem->getValueList().size() == 1)
183
+		{
184
+			QString string = flashItem->getValueList().at(0);
185
+
186
+			if(string.contains(QRegularExpression("^(\".+\")$")))
187
+			{
188
+				isString = true;
189
+
190
+				for(int j = 1; j < (string.length() - 1); j++)
191
+				{
192
+					char cChar = string.at(j).toLatin1();
193
+
194
+					if(cChar > 0)
195
+					{
196
+						flashItem->getDataVector().append(static_cast<unsigned char>(cChar));
197
+					}
198
+					else
199
+					{
200
+						compiled = false;
201
+						break;
202
+					}
203
+				}
204
+
205
+				flashItem->getDataVector().append(0x00);
206
+			}
207
+		}
208
+
209
+		if(!isString)
210
+		{
211
+			if(!flashItem->getValueList().empty())
212
+			{
213
+				for(int j = 0; j < flashItem->getValueList().size(); j++)
214
+				{
215
+					unsigned char value;
216
+
217
+					if(this->parseParamVal256(flashItem->getValueList().at(j), value))
218
+					{
219
+						flashItem->getDataVector().append(value);
220
+					}
221
+					else
222
+					{
223
+						compiled = false;
224
+						break;
225
+					}
226
+				}
227
+			}
228
+			else
229
+			{
230
+				compiled = false;
231
+			}
232
+		}
233
+
234
+		if(!compiled)
235
+		{
236
+			out << QString("ERROR: Syntax error at line %1 in file: \"%2\"\n").arg(flashItem->getLine()).arg(data.getFileName());
237
+			return(false);
238
+		}
239
+	}
240
+
241
+	return(true);
242
+}
243
+
244
+/**
245
+ * Compile the code items
246
+ *
247
+ * @param data Data of the parsed application
248
+ *
249
+ * @return Status of compiling the code items
250
+ */
251
+bool Compiler::compileCode(Data &data)
252
+{
253
+	QTextStream out(stdout);
254
+
255
+	for(const QSharedPointer<CodeSection> &codeSection : data.getCodeSectionList())
256
+	{
257
+		for(const QSharedPointer<CodeItem> &codeItem : codeSection->getCodeItemList())
258
+		{
259
+			bool compiled = false;
260
+
261
+			QVector<QList<Instruction::Arg>> arg(3);
262
+
263
+			if(codeItem->getParamList().length() == 3)
264
+			{
265
+				arg[0].append(this->checkParamType(codeItem->getParamList().at(0)));
266
+				arg[1].append(this->checkParamType(codeItem->getParamList().at(1)));
267
+				arg[2].append(this->checkParamType(codeItem->getParamList().at(2)));
268
+
269
+				for(const Instruction &instruction : this->instructionList)
270
+				{
271
+					if(!instruction.getName().compare(codeItem->getName(), Qt::CaseInsensitive))
272
+					{
273
+						if(arg[0].contains(instruction.getArgList().at(0)) && arg[1].contains(instruction.getArgList().at(1)) && arg[2].contains(instruction.getArgList().at(2)))
274
+						{
275
+							QVector<unsigned char> dataList;
276
+							QVector<unsigned char> tmp(2);
277
+							unsigned char opCode = instruction.getOpcode();
278
+							bool isOk = true;
279
+
280
+							if(instruction.getArgList().at(0) == Instruction::Arg::AB)
281
+							{
282
+								isOk &= this->parseParamAB(codeItem->getParamList().at(0), tmp[0]);
283
+								opCode |= (tmp[0] << 2);
284
+
285
+								if(instruction.getArgList().at(1) == Instruction::Arg::ABXY)
286
+								{
287
+									isOk &= this->parseParamABXY(codeItem->getParamList().at(1), tmp[0]);
288
+									opCode |= tmp[0];
289
+								}
290
+								else
291
+								{
292
+									isOk = false;
293
+								}
294
+							}
295
+							else if(instruction.getArgList().at(1) == Instruction::Arg::ABXY)
296
+							{
297
+								isOk &= this->parseParamABXY(codeItem->getParamList().at(1), tmp[0]);
298
+								opCode |= tmp[0];
299
+							}
300
+
301
+							dataList.append(opCode);
302
+
303
+							if(instruction.getArgList().at(0) == Instruction::Arg::Val256)
304
+							{
305
+								isOk &= this->parseParamVal256(codeItem->getParamList().at(0), tmp[0]);
306
+
307
+								dataList.append(tmp[0]);
308
+							}
309
+
310
+							if(instruction.getArgList().at(2) == Instruction::Arg::Addr)
311
+							{
312
+								if(isOk && this->isAddrLabel(codeItem->getParamList().at(2)))
313
+								{
314
+									codeItem->getToFillUpHash().insert(codeItem->getParamList().at(2), static_cast<unsigned int>(dataList.size()));
315
+								}
316
+								else
317
+								{
318
+									isOk &= this->parseParamAddr(codeItem->getParamList().at(2), tmp[0], tmp[1]);
319
+								}
320
+
321
+								dataList.append(tmp[0]);
322
+								dataList.append(tmp[1]);
323
+							}
324
+
325
+							if(isOk)
326
+							{
327
+								codeItem->getDataVector().append(dataList);
328
+								compiled = true;
329
+							}
330
+
331
+							break;
332
+						}
333
+					}
334
+				}
335
+			}
336
+			else if(codeItem->getParamList().length() == 2)
337
+			{
338
+				arg[0].append(this->checkParamType(codeItem->getParamList().at(0)));
339
+				arg[1].append(this->checkParamType(codeItem->getParamList().at(1)));
340
+
341
+				for(const Instruction &instruction : this->instructionList)
342
+				{
343
+					if(!instruction.getName().compare(codeItem->getName(), Qt::CaseInsensitive))
344
+					{
345
+						if(arg[0].contains(instruction.getArgList().at(0)) && arg[1].contains(instruction.getArgList().at(1)) && (instruction.getArgList().at(2) == Instruction::Arg::None))
346
+						{
347
+							QVector<unsigned char> dataList;
348
+							QVector<unsigned char> tmp(2);
349
+							unsigned char opCode = instruction.getOpcode();
350
+							bool isOk = true;
351
+
352
+							if(instruction.getArgList().at(0) == Instruction::Arg::AB)
353
+							{
354
+								isOk &= this->parseParamAB(codeItem->getParamList().at(0), tmp[0]);
355
+								opCode |= (tmp[0] << 2);
356
+
357
+								if(instruction.getArgList().at(1) == Instruction::Arg::ABXY)
358
+								{
359
+									isOk &= this->parseParamABXY(codeItem->getParamList().at(1), tmp[0]);
360
+									opCode |= tmp[0];
361
+								}
362
+								else
363
+								{
364
+									isOk = false;
365
+								}
366
+							}
367
+							else if(instruction.getArgList().at(0) == Instruction::Arg::ABXY)
368
+							{
369
+								isOk &= this->parseParamABXY(codeItem->getParamList().at(0), tmp[0]);
370
+
371
+								if(instruction.getArgList().at(1) == Instruction::Arg::ABXY)
372
+								{
373
+									isOk &= this->parseParamABXY(codeItem->getParamList().at(1), tmp[1]);
374
+									opCode |= ((tmp[0] << 2) | tmp[1]);
375
+								}
376
+								else
377
+								{
378
+									opCode |= tmp[0];
379
+								}
380
+							}
381
+							else if(instruction.getArgList().at(1) == Instruction::Arg::ABXY)
382
+							{
383
+								isOk &= this->parseParamABXY(codeItem->getParamList().at(1), tmp[0]);
384
+								opCode |= tmp[0];
385
+							}
386
+
387
+							dataList.append(opCode);
388
+
389
+							if(instruction.getArgList().at(0) == Instruction::Arg::Val256)
390
+							{
391
+								if(isOk && this->isAddrPartLabel(codeItem->getParamList().at(0)))
392
+								{
393
+									codeItem->getToFillUpHash().insert(codeItem->getParamList().at(0), static_cast<unsigned int>(dataList.size()));
394
+								}
395
+								else
396
+								{
397
+									isOk &= this->parseParamVal256(codeItem->getParamList().at(0), tmp[0]);
398
+								}
399
+
400
+								dataList.append(tmp[0]);
401
+
402
+							}
403
+							else if(instruction.getArgList().at(0) == Instruction::Arg::Addr)
404
+							{
405
+								if(isOk && this->isAddrLabel(codeItem->getParamList().at(0)))
406
+								{
407
+									codeItem->getToFillUpHash().insert(codeItem->getParamList().at(0), static_cast<unsigned int>(dataList.size()));
408
+								}
409
+								else
410
+								{
411
+									isOk &= this->parseParamAddr(codeItem->getParamList().at(0), tmp[0], tmp[1]);
412
+								}
413
+
414
+								dataList.append(tmp[0]);
415
+								dataList.append(tmp[1]);
416
+							}
417
+
418
+							if(instruction.getArgList().at(1) == Instruction::Arg::Addr)
419
+							{
420
+								if(isOk && this->isAddrLabel(codeItem->getParamList().at(1)))
421
+								{
422
+									codeItem->getToFillUpHash().insert(codeItem->getParamList().at(1), static_cast<unsigned int>(dataList.size()));
423
+								}
424
+								else
425
+								{
426
+									isOk &= this->parseParamAddr(codeItem->getParamList().at(1), tmp[0], tmp[1]);
427
+								}
428
+
429
+								dataList.append(tmp[0]);
430
+								dataList.append(tmp[1]);
431
+							}
432
+							if(isOk)
433
+							{
434
+								if(instruction.getOpcodeSecond() != 0)
435
+								{
436
+									opCode = instruction.getOpcodeSecond();
437
+
438
+									if(instruction.getArgSecondList().at(0) == Instruction::Arg::ABXY)
439
+									{
440
+										isOk &= this->parseParamABXY(codeItem->getParamList().at(0), tmp[0]);
441
+										opCode |= tmp[0];
442
+									}
443
+
444
+									dataList.append(opCode);
445
+								}
446
+
447
+								if(isOk)
448
+								{
449
+									codeItem->getDataVector().append(dataList);
450
+									compiled = true;
451
+								}
452
+							}
453
+
454
+							break;
455
+						}
456
+					}
457
+				}
458
+			}
459
+			else if(codeItem->getParamList().length() == 1)
460
+			{
461
+				arg[0].append(this->checkParamType(codeItem->getParamList().at(0)));
462
+
463
+				for(const Instruction &instruction : this->instructionList)
464
+				{
465
+					if(!instruction.getName().compare(codeItem->getName(), Qt::CaseInsensitive))
466
+					{
467
+						if(arg[0].contains(instruction.getArgList().at(0)) && (instruction.getArgList().at(1) == Instruction::Arg::None) && (instruction.getArgList().at(2) == Instruction::Arg::None))
468
+						{
469
+							QVector<unsigned char> dataList;
470
+							QVector<unsigned char> tmp(2);
471
+							unsigned char opCode = instruction.getOpcode();
472
+							bool isOk = true;
473
+
474
+							if(instruction.getArgList().at(0) == Instruction::Arg::ABXY)
475
+							{
476
+								isOk &= this->parseParamABXY(codeItem->getParamList().at(0), tmp[0]);
477
+								opCode |= tmp[0];
478
+							}
479
+
480
+							dataList.append(opCode);
481
+
482
+							if(instruction.getArgList().at(0) == Instruction::Arg::Val256)
483
+							{
484
+								if(isOk && this->isAddrPartLabel(codeItem->getParamList().at(0)))
485
+								{
486
+									codeItem->getToFillUpHash().insert(codeItem->getParamList().at(0), static_cast<unsigned int>(dataList.size()));
487
+								}
488
+								else
489
+								{
490
+									isOk &= this->parseParamVal256(codeItem->getParamList().at(0), tmp[0]);
491
+								}
492
+
493
+								dataList.append(tmp[0]);
494
+							}
495
+							else if(instruction.getArgList().at(0) == Instruction::Arg::Addr)
496
+							{
497
+								if(isOk && this->isAddrLabel(codeItem->getParamList().at(0)))
498
+								{
499
+									codeItem->getToFillUpHash().insert(codeItem->getParamList().at(0), static_cast<unsigned int>(dataList.size()));
500
+								}
501
+								else
502
+								{
503
+									isOk &= this->parseParamAddr(codeItem->getParamList().at(0), tmp[0], tmp[1]);
504
+								}
505
+
506
+								dataList.append(tmp[0]);
507
+								dataList.append(tmp[1]);
508
+							}
509
+
510
+							if(isOk)
511
+							{
512
+								codeItem->getDataVector().append(dataList);
513
+								compiled = true;
514
+							}
515
+
516
+							break;
517
+						}
518
+					}
519
+				}
520
+			}
521
+			else
522
+			{
523
+				for(const Instruction &instruction : this->instructionList)
524
+				{
525
+					if(!instruction.getName().compare(codeItem->getName(), Qt::CaseInsensitive))
526
+					{
527
+						if((instruction.getArgList().at(0) == Instruction::Arg::None) && (instruction.getArgList().at(1) == Instruction::Arg::None) && (instruction.getArgList().at(2) == Instruction::Arg::None))
528
+						{
529
+							codeItem->getDataVector().append(instruction.getOpcode());
530
+							compiled = true;
531
+
532
+							break;
533
+						}
534
+					}
535
+				}
536
+			}
537
+
538
+			if(!compiled)
539
+			{
540
+				out << QString("ERROR: Syntax error at line %1 in file: \"%2\"\n").arg(codeItem->getLine()).arg(data.getFileName());
541
+				return(false);
542
+			}
543
+		}
544
+	}
545
+
546
+	return(true);
547
+}
548
+
549
+/**
550
+ * Parse the string and return AB
551
+ *
552
+ * @param param String to parsing
553
+ * @param value Parsed value
554
+ *
555
+ * @return Status of parsing the string
556
+ */
557
+bool Compiler::parseParamAB(const QString &param, unsigned char &value)
558
+{
559
+	if(!param.compare("a", Qt::CaseInsensitive))
560
+	{
561
+		value = 0;
562
+	}
563
+	else if(!param.compare("b", Qt::CaseInsensitive))
564
+	{
565
+		value = 1;
566
+	}
567
+	else
568
+	{
569
+		return(false);
570
+	}
571
+
572
+	return(true);
573
+}
574
+
575
+/**
576
+ * Parse the string and return ABXY
577
+ *
578
+ * @param param String to parsing
579
+ * @param value Parsed value
580
+ *
581
+ * @return Status of parsing the string
582
+ */
583
+bool Compiler::parseParamABXY(const QString &param, unsigned char &value)
584
+{
585
+	if(!param.compare("a", Qt::CaseInsensitive))
586
+	{
587
+		value = 0;
588
+	}
589
+	else if(!param.compare("b", Qt::CaseInsensitive))
590
+	{
591
+		value = 1;
592
+	}
593
+	else if(!param.compare("x", Qt::CaseInsensitive))
594
+	{
595
+		value = 2;
596
+	}
597
+	else if(!param.compare("y", Qt::CaseInsensitive))
598
+	{
599
+		value = 3;
600
+	}
601
+	else
602
+	{
603
+		return(false);
604
+	}
605
+
606
+	return(true);
607
+}
608
+
609
+/**
610
+ * Parse the string and return Val256
611
+ *
612
+ * @param param String to parsing
613
+ * @param value Parsed value
614
+ *
615
+ * @return Status of parsing the string
616
+ */
617
+bool Compiler::parseParamVal256(const QString &param, unsigned char &value)
618
+{
619
+	bool isOk = false;
620
+	unsigned int number = 0;
621
+
622
+	if(param.contains(QRegularExpression("^([0-9]+)$")))
623
+	{
624
+		number = param.toUInt(&isOk, 10);
625
+	}
626
+	else if(param.contains(QRegularExpression("^(0b[01]+)$")))
627
+	{
628
+		number = param.midRef(2).toUInt(&isOk, 2);
629
+	}
630
+	else if(param.contains(QRegularExpression("^(0x[0-9abcdefABCDEF]+)$")))
631
+	{
632
+		number = param.midRef(2).toUInt(&isOk, 16);
633
+	}
634
+	else if(param.contains(QRegularExpression("^('.')$")))
635
+	{
636
+		char cChar = param.at(1).toLatin1();
637
+
638
+		if(cChar > 0)
639
+		{
640
+			number = static_cast<unsigned int>(cChar);
641
+			isOk = true;
642
+		}
643
+	}
644
+
645
+	if(isOk)
646
+	{
647
+		if(number < 256)
648
+		{
649
+			value = static_cast<unsigned char>(number);
650
+		}
651
+		else
652
+		{
653
+			isOk = false;
654
+		}
655
+	}
656
+
657
+	return(isOk);
658
+}
659
+
660
+/**
661
+ * Parse the string and return address
662
+ *
663
+ * @param param String to parsing
664
+ * @param valueLow Parsed lower byte of the value
665
+ * @param valueHigh Parsed higher byte of the value
666
+ *
667
+ * @return Status of parsing the string
668
+ */
669
+bool Compiler::parseParamAddr(const QString &param, unsigned char &valueLow, unsigned char &valueHigh)
670
+{
671
+	bool isOk = false;
672
+	unsigned int number = 0;
673
+
674
+	if(param.contains(QRegularExpression("^(0x[0-9abcdefABCDEF]+)$")))
675
+	{
676
+		number = param.midRef(2).toUInt(&isOk, 16);
677
+	}
678
+
679
+	if(isOk)
680
+	{
681
+		if(number < Data::MEMORY_SIZE)
682
+		{
683
+			valueLow = static_cast<unsigned char>(number % 256);
684
+			valueHigh = static_cast<unsigned char>(number / 256);
685
+		}
686
+		else
687
+		{
688
+			isOk = false;
689
+		}
690
+	}
691
+
692
+	return(isOk);
693
+}
694
+
695
+/**
696
+ * Check if the param is an address label
697
+ *
698
+ * @param param String to check
699
+ *
700
+ * @return Status of the check
701
+ */
702
+bool Compiler::isAddrLabel(const QString &param) const
703
+{
704
+	if(param.contains(QRegularExpression(R"(^(\.[0-9a-zA-Z_-]+)$)")))
705
+	{
706
+		return(true);
707
+	}
708
+	else if(param.contains(QRegularExpression(R"(^(\*[0-9a-zA-Z_-]+)$)")))
709
+	{
710
+		return(true);
711
+	}
712
+	else if(param.contains(QRegularExpression(R"(^(\*[0-9a-zA-Z_-]+\[[0-9]+\])$)")))
713
+	{
714
+		return(true);
715
+	}
716
+
717
+	return(false);
718
+}
719
+
720
+/**
721
+ * Check if the param is a low or high address
722
+ *
723
+ * @param param String to check
724
+ *
725
+ * @return Status of the check
726
+ */
727
+bool Compiler::isAddrPartLabel(const QString &param) const
728
+{
729
+	if(param.contains(QRegularExpression(R"(^((low|high)\(\.[0-9a-zA-Z_-]+\))$)")))
730
+	{
731
+		return(true);
732
+	}
733
+	else if(param.contains(QRegularExpression(R"(^((low|high)\(\*[0-9a-zA-Z_-]+\))$)")))
734
+	{
735
+		return(true);
736
+	}
737
+	else if(param.contains(QRegularExpression(R"(^((low|high)\(\*[0-9a-zA-Z_-]+\[[0-9]+\]\))$)")))
738
+	{
739
+		return(true);
740
+	}
741
+
742
+	return(false);
743
+}