GithubHelp home page GithubHelp logo

sqfvm / runtime Goto Github PK

View Code? Open in Web Editor NEW
95.0 9.0 29.0 11.56 MB

Custom implementation of the Arma script language SQF

License: GNU Lesser General Public License v3.0

C 0.32% C++ 92.95% Makefile 1.12% CMake 0.37% SQF 5.04% Python 0.20% Dockerfile 0.01%
scripting-language discord sqf-vm arma arma3 vm stack-based cpp cplusplus sqf

runtime's People

Contributors

4d4a5852 avatar billw2012 avatar casperento avatar dahlgren avatar darkwanderer avatar dedmen avatar dextercd avatar keithenneu avatar krzmbrzl avatar pabstmirror avatar spicybagpipes avatar vasama avatar x39 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

runtime's Issues

[BUG] Trigonometric functions use radians in SQF-VM, but degrees in Arma 3

Describe the bug
All of the trigonometric functions (cos, tan, sin, etc) in SQF-VM are backed by the underlying C++ std library functions of the same name.

However, C++ uses radians exclusively for parameters + return values, whereas Arma 3 uses degrees.
SQF-VM needs to convert degrees to radians before passing it to the underlying std:: functions.

To Reproduce
Steps to reproduce the behavior:

  1. Do sin 30 in SQF-VM. Correct value is 0.5, actual value is not.

Expected behavior
sin 30 takes degrees, and returns 0.5.

Additional context
Affected operators are (in order of appearance in ops_math.cpp)

  • atan2
  • sin
  • acos
  • tan
  • asin
  • atan
  • cos
  • atg (same internal implementation as atan)

[BUG] ASM->SQF conversion array swap

Describe the bug

While writing this test, I had the wrong result flag (true instead of false)
https://github.com/SQFvm/vm/blob/master/tests/sqf/namespace.sqf#L12
And it printed this:
[CHAT] SYSTEM: Test !FAILED! '\sqf\namespace.sqf' - 8 { missionNamespace getVariable [false, "don'texist"] }

The code is
{ missionNamespace getVariable ["don'texist", false] }
But the ASM->SQF conversion printed
{ missionNamespace getVariable [false, "don'texist"] }
instead. Swapping the array entries.

To Reproduce
Steps to reproduce the behavior:
Change https://github.com/SQFvm/vm/blob/master/tests/sqf/namespace.sqf#L12
to
["assertEqual", { missionNamespace getVariable ["don'texist", false] }, true],
and watch the test error

Function call with params in a conditional in a call statement gives error.

fn_a = {
    true
};

fn_b = {
    params ["_ignore"];
    true
};

// works
val = [] call (if([] call fn_a) then { fn_a } else { fn_a });

// doesn't work, only difference is that fn_b has params
val2 = [] call (if([true] call fn_b) then { fn_a } else { fn_a });
val2 = [] call (if([true] call fn_
          ^^^^
[WRN][12|C6]    callBinary could not receive a value for left arg.
[WORK]    <ARRAY>    []

[BUG] Switch foreach case looses _forEachIndex

Describe the bug
Using foreach around a switch containing the case clauses will cause the variable tree to loose the _forEachIndex variable.

To Reproduce
Steps to reproduce the behavior:

  1. Execute code below
  2. Check output

Expected behavior
2. Output should resemble _testarray

Additional context

private _testarray = [1, 2, 3, 4 ,5, 6];
private _a = 3;
switch (_a) do
{
    {
        case _x: { hint str (_testarray select (_forEachIndex + 1)) };
    } foreach _testarray
};

[BUG] Switch case return handling not correct

Describe the bug
Seems like switch always returns nil, but it should return the value that the last case/default returned.

To Reproduce

_taskFunction = {
case 1: {"a"}; 
case 2: {"b"};
case 3: {"c"};
};
_value = switch 2 do {
call _taskFunction;
default {"default"}
};
_value

Expected:
[WORK] "b"

Actual:
[WORK] <EMPTY>

_taskFunction = {
case 1: {"a"}; 
case 2: {"b"};
case 3: {"c"};
};
_value = switch 2 do {
call _taskFunction;
default {"default"}
};
hint _value;
_value

Expected:
[HINT] b

Actual:

[RNT][L12|C0|__libraryfeed.sqf]    callUnary could not receive a value for right arg.
Stacktrace:
1:    namespace: missionNamespace    scopename:     callstack: callstack
[STT][L12|C0|__libraryfeed.sqf]    
[WORK]    <EMPTY>

Create test-cases

To create a test case, create another file like this: https://github.com/SQFvm/vm/blob/master/tests/sqf/select.sqf at https://github.com/SQFvm/vm/blob/master/tests/sqf/

  • parsingnamespace
  • pi
  • nil
  • east
  • missionnamespace
  • uinamespace
  • profilenamespace
  • productversion
  • cansuspend
  • allunits
  • diag_ticktime
  • pwd__
  • halt
  • cmdsimplemented__
  • cmds__
  • allobjects__
  • exit__
  • vm__
  • respawn__
  • callstack__
  • currentdirectory__
  • true
  • false
  • confignull
  • configfile
  • allmapmarkers
  • blufor
  • west
  • opfor
  • resistance
  • player
  • independent
  • civilian
  • sideempty
  • sideenemy
  • grpnull
  • sidefriendly
  • sidelogic
  • sideunknown
  • objnull
  • assert BOOL
  • abs SCALAR
  • round SCALAR
  • sqrt SCALAR
  • deg SCALAR
  • acos SCALAR
  • selectmax ARRAY
  • log SCALAR
  • sin SCALAR
  • tan SCALAR
  • exp SCALAR
  • rad SCALAR
  • random SCALAR
  • hint STRING
  • hint TEXT
  • - SCALAR
  • systemchat STRING
  • gunner OBJECT
  • + SCALAR
  • + NaN
  • + ARRAY
  • ! BOOL
  • floor SCALAR
  • sleep SCALAR
  • ceil SCALAR
  • asin SCALAR
  • preprocessfilelinenumbers STRING
  • selectmin ARRAY
  • ln SCALAR
  • atan SCALAR
  • allvariables NAMESPACE
  • allvariables OBJECT
  • allvariables GROUP
  • atg SCALAR
  • isnil STRING
  • isnil CODE
  • units GROUP
  • units OBJECT
  • cos SCALAR
  • private STRING
  • private ARRAY
  • vectormagnitude ARRAY
  • scriptdone SCRIPT
  • vectormagnitudesqr ARRAY
  • vectornormalized ARRAY
  • tofixed SCALAR
  • preprocess__ STRING
  • call CODE
  • with NAMESPACE
  • count ARRAY
  • count STRING
  • count CONFIG
  • default CODE
  • comment STRING
  • side GROUP
  • side OBJECT
  • compile STRING
  • while CODE
  • typename ANY
  • for STRING
  • str ANY
  • if BOOL
  • alive OBJECT
  • selectrandom ARRAY
  • reverse ARRAY
  • scriptname STRING
  • case ANY
  • switch ANY
  • params ARRAY
  • velocity OBJECT
  • param ARRAY
  • preprocessfile STRING
  • preprocessfile STRING
  • diag_log ANY
  • tree__ STRING
  • help__ STRING
  • typeof OBJECT
  • markershape STRING
  • configparse__ STRING
  • prettyprintsqf__ STRING
  • assembly__ CODE
  • allfiles__ ARRAY
  • trim__ STRING
  • tolower STRING
  • toupper STRING
  • format ARRAY
  • toarray STRING
  • tostring ARRAY
  • configname CONFIG
  • confighierarchy CONFIG
  • inheritsfrom CONFIG
  • markertext STRING
  • isnumber CONFIG
  • istext CONFIG
  • vehicle OBJECT
  • isclass CONFIG
  • isarray CONFIG
  • getnumber CONFIG
  • gettext CONFIG
  • getarray CONFIG
  • isnull CONFIG
  • isnull GROUP
  • isnull OBJECT
  • configproperties ARRAY
  • creategroup SIDE
  • groupid GROUP
  • deletegroup GROUP
  • createvehicle ARRAY
  • deletevehicle OBJECT
  • position OBJECT
  • getpos OBJECT
  • nearestobjects ARRAY
  • getdammage OBJECT
  • damage OBJECT
  • crew OBJECT
  • objectparent OBJECT
  • driver OBJECT
  • commander OBJECT
  • getmarkertype STRING
  • markertype STRING
  • getmarkersize STRING
  • markersize STRING
  • getmarkercolor STRING
  • markercolor STRING
  • getmarkerpos STRING
  • markerpos STRING
  • markerbrush STRING
  • markerdir STRING
  • markeralpha STRING
  • createmarker ARRAY
  • createmarkerlocal ARRAY
  • deletemarker STRING
  • deletemarkerlocal STRING
  • SCALAR min SCALAR
  • SCALAR atan2 SCALAR
  • SCALAR ^ SCALAR
  • CODE foreach ARRAY
  • ARRAY vectoradd ARRAY
  • ARRAY vectordiff ARRAY
  • SCALAR max SCALAR
  • ANY != ANY
  • SIDE != SIDE
  • STRING != STRING
  • OBJECT != OBJECT
  • GROUP != GROUP
  • TEXT != TEXT
  • CONFIG != CONFIG
  • DISPLAY != DISPLAY
  • CONTROL != CONTROL
  • LOCATION != LOCATION
  • ARRAY set ARRAY
  • SCALAR mod SCALAR
  • SCALAR - SCALAR
  • ARRAY - ARRAY
  • SCALAR % SCALAR
  • ARRAY pushback ANY
  • SCALAR + SCALAR
  • ARRAY + ARRAY
  • STRING + STRING
  • ARRAY findif CODE
  • SCALAR * SCALAR
  • ANY in ARRAY
  • OBJECT in OBJECT
  • SCALAR / SCALAR
  • CONFIG / STRING
  • ARRAY vectorcos ARRAY
  • SCALAR > SCALAR
  • ARRAY append ARRAY
  • ARRAY vectorcrossproduct ARRAY
  • ARRAY resize SCALAR
  • IF exitwith CODE
  • ANY call CODE
  • ARRAY vectordistance ARRAY
  • BOOL && BOOL
  • BOOL && CODE
  • ARRAY vectordistancesqr ARRAY
  • SWITCH : CODE
  • ARRAY select SCALAR
  • ARRAY select BOOL
  • ARRAY select ARRAY
  • ARRAY select CODE
  • CODE select ARRAY
  • STRING select ARRAY
  • CONFIG select SCALAR
  • ANY spawn CODE
  • ARRAY vectordotproduct ARRAY
  • SCALAR <= SCALAR
  • STRING setmarkertext STRING
  • ANY param ARRAY
  • ARRAY vectormultiply SCALAR
  • SCALAR tofixed SCALAR
  • WITH do CODE
  • WHILE do CODE
  • FOR do CODE
  • SWITCH do CODE
  • SCALAR >= SCALAR
  • NAMESPACE getvariable STRING
  • NAMESPACE getvariable ARRAY
  • OBJECT getvariable STRING
  • OBJECT getvariable ARRAY
  • GROUP getvariable STRING
  • GROUP getvariable ARRAY
  • BOOL == BOOL
  • SCALAR == SCALAR
  • SIDE == SIDE
  • STRING == STRING
  • OBJECT == OBJECT
  • GROUP == GROUP
  • TEXT == TEXT
  • CONFIG == CONFIG
  • DISPLAY == DISPLAY
  • CONTROL == CONTROL
  • LOCATION == LOCATION
  • FOR step SCALAR
  • NAMESPACE setvariable ARRAY
  • OBJECT setvariable ARRAY
  • GROUP setvariable ARRAY
  • ARRAY joinstring STRING
  • OBJECT setvelocity ARRAY
  • CODE count ARRAY
  • STRING callextension STRING
  • STRING callextension ARRAY
  • IF then ARRAY
  • IF then CODE
  • CODE else CODE
  • ARRAY pushbackunique ANY
  • FOR from SCALAR
  • FOR to SCALAR
  • STRING setmarkercolor STRING
  • ARRAY # SCALAR
  • ARRAY sort BOOL
  • SCALAR < SCALAR
  • ARRAY apply CODE
  • STRING setmarkerbrush STRING
  • ARRAY deleteat SCALAR
  • ARRAY arrayintersect ARRAY
  • ARRAY find ANY
  • STRING find STRING
  • ARRAY params ARRAY
  • CONFIG merge__ CONFIG
  • CODE except__ CODE
  • BOOL and BOOL
  • BOOL and CODE
  • BOOL || BOOL
  • BOOL || CODE
  • BOOL or BOOL
  • BOOL or CODE
  • ANY isequalto ANY
  • ANY isequaltype ANY
  • STRING createvehicle ARRAY
  • CONFIG >> STRING
  • STRING configclasses CONFIG
  • ANY createvehiclelocal ANY
  • OBJECT setpos ARRAY
  • OBJECT domove ARRAY
  • ARRAY domove ARRAY
  • GROUP createunit ARRAY
  • STRING createunit ARRAY
  • ARRAY distance ARRAY
  • OBJECT distance ARRAY
  • ARRAY distance OBJECT
  • OBJECT distance OBJECT
  • OBJECT iskindof STRING
  • STRING iskindof STRING
  • STRING iskindof ARRAY
  • OBJECT setdamage SCALAR
  • STRING setmarkershape STRING
  • STRING setmarkershapelocal STRING
  • STRING setmarkerbrushlocal STRING
  • STRING setmarkerpos ARRAY
  • STRING setmarkerposlocal ARRAY
  • STRING setmarkertype STRING
  • STRING setmarkertypelocal STRING
  • STRING setmarkertextlocal STRING
  • STRING setmarkerdir SCALAR
  • STRING setmarkerdirlocal SCALAR
  • STRING setmarkercolorlocal STRING
  • STRING setmarkersize ARRAY
  • STRING setmarkersizelocal ARRAY
  • STRING setmarkeralpha SCALAR
  • STRING setmarkeralphalocal SCALAR
  • try CODE
  • EXCEPTION catch CODE
  • throw ANY
  • STRING composeText ARRAY
  • lineBreak
  • parseText STRING
  • text STRING
  • STRING splitString STRING
  • GROUP selectLeader OBJECT
  • ARRAY matrixMultiply ARRAY
  • matrixTranspose ARRAY
  • ANY isNotEqualTo ANY
  • OBJECT distance2d OBJECT
  • OBJECT distance2d ARRAY
  • ARRAY distance2d OBJECT
  • ARRAY distance2d ARRAY
  • ARRAY deleteRange ARRAY
  • breakOut STRING
  • ANY breakOut STRING
  • not BOOL

[BUG] Config parser - Unexpected errors with GUI controls array

Describe the bug
The config parser errors when parsing a GUI's controls[].

To Reproduce

  1. Create file test.cpp, containing:
class My_Dialog {
	controls[] = { My_Text_1 };
	class My_Text_1 {};
};
  1. Execute sqfvm.exe --parse-only --input-config test.cpp
  2. See errors:
[ERR] [L2|C16|file]      Missing curly closing bracket (`}`).
[ERR] [L2|C16|file]      Expected Statement termination using `;`.
[ERR] [L2|C26|file]      Missing equal sign (`=`).

Expected behavior
No error.

Screenshots
N/A

Additional context
N/A

[BUG] Config parser doesn't support external base classes

Describe the bug
Config parser doesn't support external base classes.

To Reproduce

  1. Create a file named config.cpp, containing:
class externalBaseClass;
class myClass: externalBaseClass {};
  1. Execute sqfvm.exe -a --parse-only --input-config config.cpp
  2. See error

Expected behavior
No error when using external base classes.

Screenshots
N/A

Additional context
N/A

isNil {} hangs.

isNil {};
This will stop further execution. It works in Arma (we use it for emulating a critical section).

Macro in another macro call is behaving strangely

#define MACRO() []
#define MACRO2(a, b) private a = b
MACRO2(_a, MACRO());
ate _a =  MACRO);
               ^
[ERR][L3|C17|__libraryfeed.sqf]    Reached EOF before finishing parsing.
[WORK]    <EMPTY> 
#define MACRO(a) a
#define MACRO2(a, b) private a = b
MACRO2(_a, MACRO(0));
private _a =  0;
              ^
[RNT][L3|C12|__libraryfeed.sqf]    [ERR][L3|C8|__libraryfeed.sqf]    Arg Count Missmatch.
[WORK]    <SCALAR>    0

[BUG] exitWith does not end loops

Expected behaviour:

for "_i" from 0 to 1 do
{
	assert (_i == 0);
	if true exitWith {};
};

local _i = 0;
while { true } do
{
	assert (_i == 0);
	_i = _i + 1;
	if true exitWith {};
};

Macro concat error

@SQF#3423 
#define QUOTE(x) #x
#define QGVAR(x) QUOTE(ace_test_##x)
#define HIT_STRUCTURAL QGVAR($#structural)
HIT_STRUCTURAL

Actual:
[WORK] <STRING> ace_test_##$#structural
Expected:
[WORK] <STRING> ace_test_$#structural

[BUG] Multiple same file includes causes Recursive include detected

Describe the bug
If a file is included multiple times, Recursive include detected. Include Tree. is received.

To Reproduce

  1. Create empty file named include.sqf
  2. Execute
#include "include.sqf"
#include "include.sqf"
  1. See error Recursive include detected. Include Tree.

Expected behavior
No error thrown when including the same file, multiple times.

Screenshots
N/A

Additional context
N/A

Run SQF Unit Test suites via SQFvm

Is your feature request related to a problem? Please describe.
I would love to run Unit Tests very easily against the SQFvm

Describe the solution you'd like
Best case I just refer to my SQF sources and test files and then magic happens

Describe alternatives you've considered
no alternatives accepted

Additional context
Starting ArmA3 only to see if my unit tests go green is a big time waster. SQFvm could be the best thing existing if a testing engine would be available!

__FILE__ __LINE__ macros resolve to wrong data

#define LOG(x) diag_log [x, FILE, LINE];

LOG(a)
LOG(a)
LOG(a)

Actual:

[DIAG]    [nil,"__libraryfeed.sqf",1]
[DIAG]    [nil,"__libraryfeed.sqf",1]
[DIAG]    [nil,"__libraryfeed.sqf",1]

Expected:

[DIAG]    [nil,"__libraryfeed.sqf",3]
[DIAG]    [nil,"__libraryfeed.sqf",4]
[DIAG]    [nil,"__libraryfeed.sqf",5]

Or
macro.hpp:

#define LOG(x) diag_log [x, FILE, LINE];

script.sqf:

#include "macro.hpp"
LOG(a)
LOG(b)

Actual:

[DIAG]    [nil,"macro.hpp",1]
[DIAG]    [nil,"macro.hpp",1]

Expected:

[DIAG]    [nil,"script.sqf",2]
[DIAG]    [nil,"script.sqf",3]

Warn on unused PreProcessor arg

  1. // Should create a warning because unused is not being used in the macro but present in the define
    #define foo(unused) bar
    foo(something)

  2. // Should not create a warning as define contents are empty
    #define foo(unused)
    foo(something)

[BUG] Virtual argument's virtual path is case-sensitive

Describe the bug
--virtual's virtual path is case-sensitive

To Reproduce

  1. Create file test.cpp, containing #include "\A3\3den\ui\macros.inc"
  2. Execute sqfvm.exe --parse-only --virtual "P:\a3|a3" --input-config test.cpp
  3. See error Failed to include '\A3\3den\ui\macros.inc'
  4. Execute sqfvm.exe --parse-only --virtual "P:\a3|A3" --input-config test.cpp
  5. Notice no error.

Expected behavior
Virtual path to be case-insensitive.

Screenshots
N/A

Additional context
N/A

[BUG] Config parser - Lack of whitespace causes "Missing curly closing bracket" error

Describe the bug
The config parser throws a "Missing curly closing bracket" error, if there is no whitespace between the block content semicolon and closing curly brace.

To Reproduce

  1. Execute configparse__ "class A {a=1;};"
  2. See error: [ERR] [L1|C16|file] Missing curly closing bracket (}).
  3. Execute configparse__ "class A {a=1; };"
  4. Notice no error

Expected behavior
No error.

Screenshots
N/A

Additional context
N/A

Missing filename in error reports from execution.

Parsing produces error reports with file name on the next line, but in execution file name is missing. Ideally please have a standardized one line error format so IDEs (and simple regex) can pick it up.
e.g. https://blogs.msdn.microsoft.com/msbuild/2006/11/02/msbuild-visual-studio-aware-error-messages-and-message-formats/

Visual Studio Code can support a number of different formats out of the box as seen here: https://code.visualstudio.com/docs/editor/tasks#_processing-task-output-with-problem-matchers

preprocessor should always add `#file` to first line

To allow commands like preprocessFile to return what files they processed and thus let compile know where a given instruction is located at, the #file instruction should be placed at the very start of every file (unless the path is not provided).

Macro resolution error

#define DOUBLES(var1,var2) var1##_##var2
#define PREFIX ace
#define COMPONENT medical_engine
#define ADDON DOUBLES(PREFIX,COMPONENT)
#define GVAR(var1) DOUBLES(ADDON,var1)
#define QUOTE(x) #x
#define QGVAR(var1) QUOTE(GVAR(var1))
#define HIT_STRUCTURAL QGVAR($#structural)
[HIT_STRUCTURAL, 0]

Actual:
["ace_medical_engine_$"tructural"", 0]

dical_engine_$"tructural"", 0]
               ^^^^^^^^^
[ERR][L9|C23|P:\x64\__commandlinefeed.sqf]      Expected ']'.
dical_engine_$"tructural"", 0]
               ^^^^^^^^^
[ERR][L9|C23|P:\x64\__commandlinefeed.sqf]      Expected either ';' or ','.
ine_$"tructural"", 0]
               ^
[ERR][L9|C32|P:\x64\__commandlinefeed.sqf]      Expected either ';' or ','.
Executing...
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
[WORK]  <EMPTY>

Expected:
["ace_medical_engine_$#structural", 0]

Deadlock when using global var for conditional call/compile.

init.sqf:

diag_log "including test.hpp";
#include "test.hpp"

test.hpp:

diag_log "in test.hpp: checking test_init";
if(isNil "test_init") then {
	diag_log "test_init is nil, calling test.sqf";
	call compile preprocessFileLineNumbers "test.sqf"; 
};

test.sqf:

diag_log "in test.sqf: test_init set to true";
test_init = true;
#include "test.hpp"

Arma rpt reads:

22:19:43 "including test.hpp"
22:19:43 "in test.hpp: checking test_init"
22:19:43 "test_init is nil, calling test.sqf"
22:19:43 "in test.sqf: test_init set to true"
22:19:43 "in test.hpp: checking test_init"

SQF-vm repeats forever:

...
[DIAG]  in test.hpp: checking test_init
[DIAG]  test_init is nil, calling test.sqf
[DIAG]  in test.sqf: test_init set to true
[DIAG]  in test.hpp: checking test_init

Issues with forEach variable scoping

{
    diag_log [_i];
    _i = 123;
} foreach [1,2,3]

Result:

[DIAG]    [nil]
[DIAG]    [123]
[DIAG]    [123]
[WORK]    <EMPTY>

Expected:

[DIAG]    [nil]
[DIAG]    [nil]
[DIAG]    [nil]
[WORK]    <EMPTY>

Variable scope is destroyed after each iteration. all variables should be gone.

[Separation of Concerns] Main Ticket - Split up this repository

Repository should be split up into:

  • runtime
  • filesystem
  • parser-sqf
  • parser-preproc
  • parser-config
  • cli (CommandLineInterface)
  • library (Should contain all dependencies required to link against full SQF-VM)
  • operators (???)
  • ???

That way, everyone may pick the part he likes the most/wants to replace.

  • During splitting, cleaner API designs should be considered (modular runtime)
  • Further tickets shall be created for every sub-feature.
  • Sub-Features should be placed inside this repository until all are completed. Only then they shall be split up into separate repositories.

Useful Links:

[BUG] Pasting script with empty lines only executes till empty line

Describe the bug
When pasting a piece of code in the VM which contains empty lines, it will only execute the part till the first empty line.

To Reproduce
Steps to reproduce the behavior:

  1. Paste the following example in the VM (without empty line):
test_fnc_print = {
    params ["_value"];
    diag_log(format ["%1", _value]);
};
["some test"] call text_fnc_print;
  1. Run the code
  2. RESULT: [WORK] <ARRAY> ["some test"]
  3. Paste the folling example in the VM (with empty line):
test_fnc_print = {
    params ["_value"];
    diag_log(format ["%1", _value]);
};

["some test"] call text_fnc_print;
  1. Run the code
  2. RESULT: [WORK] <EMPTY>
    6.a. It also prints the last line (after empty line) as a new piece of code.

Expected behavior
I would expect that "any" code, with or without empty lines (for readability) are executed properly.

Screenshots
sqmvm

Additional context
Tested with 1.3.1-RC1 (Win64.x64)

[BUG] Preprocessor doesn't join all escaped newlines

To Reproduce
Preprocess this:

"a test\
"

Actual output:

"a test\
"

Expected output:

"a test"

Preprocess this:

diag_log 'a';\
diag_log 'b';

Actual output:

diag_log 'a';\
diag_log 'b';

Expected output:

diag_log 'a';diag_log 'b';

Inconsistent pathing in error messages.

Sometimes absolute, sometimes relative. They should be consistent, either always relative or always absolute, not a mixture, regardless of how the path was introduced to the compiler.
This helps with parsing and reading.

[ERR][L338|C8|OOP_Light\OOP_Light_init.sqf]     Expected either ';' or ','.
E__, __LINE__] call OOP_assert_cla
               ^^^^
[RNT][L11|C249|c:\Users\billw\Documents\Arma 3\mpmissions\CmdrAITestbed.Altis\scripts\RefCountedTest.sqf]       callBinary could not receive a value for right arg.
[WORK]  <ARRAY> ["RefCounted",nil,nil]

[BUG] Config parser - Output of "Exiting due to error." is inverted

Describe the bug
Verbose config parsing outputs "Exiting due to error." when no error occurs and doesn't output it when an error occurs.

To Reproduce

  1. Create file test.cpp, containing class A {}
  2. Execute sqfvm.exe --verbose --parse-only --input-config test.cpp
  3. Notice no errors, but Exiting due to error. is displayed.
  4. Change content of test.cpp to class A {
  5. Repeat step 2.
  6. Notice errors, but no Exiting due to error..

Expected behavior
"Exiting due to error." outputted when an error occurs, instead of when none occur.

Screenshots
N/A

Additional context

return !errflag;

[BUG] Nested IF(N)DEF error with included IF(N)DEF

Describe the bug
Unexpected IFNDEF. Already inside of a IFDEF or IFNDEF enclosure. is received when an include, containing a ifdef/ifndef, is wrapped with a ifdef/ifndef.

To Reproduce

  1. Create a file named include.sqf, containing:
#ifndef UNDEFINED
systemChat "Foo";
#endif
  1. Execute:
#ifndef UNDEFINED
#include "include.sqf"
#endif
  1. See errror Unexpected IFNDEF. Already inside of a IFDEF or IFNDEF enclosure.

Expected behavior
No error when if(n)def is used inside of an include file, wrapped in a if(n)def.

Screenshots
sqfVM_includeWrapDef
arma_includeWrapDef png

Additional context
N/A

Mock convenient BIS functions and commands

I played around with your tool and well found it pretty cool for hacking some sqf scripts while on the run. But I am missing the use of commands and functions like findNearestEnemy.

I was tinkering in my head if it might be a solution if we have to provide some kind of mocked function list. For instance consider this mock-function.sqfmock fictional file (I am scripting for a month - please don't judge my syntax):

var mockedUnits  = createGroup west; // create a mockedUnits group
var mockedFoundEnemy = mockedUnits createUnit [type, position, markers, placement, special] // setting right parameters
_ findNearestEnemy _ >> mockedFoundEnemy // tell the function with >> to return the given object regardless of the parameters given (type, etc.)

Explaination
The first two lines are the test objects that have to be created because findNearestEnemy should return the mockedFoundEnemy regardless with what parameters the function is called ( the _ indicates a wildcard for parameters)

So after "loading" this mock-function.sqfmock into the CLI I can run the following within the REPL

// objects defined before this
someObject findNearestEnemy somePosition;

And the REPL will return the mockedFoundEnemy object. This way I am able to write my functions and use these commands and BIS functions. Implied that this mock-function.sqfmock has the needed functions mocked which is a good piece of work - but hey - maybe a community could kind of contribute to a huge mock file.

I hope you understand what I mean

PS: The idea and syntax is inspired by the Java Spock Testing Framework

[BUG] Config parser - Inconsistent and unexpected "Missing equal sign" error

Describe the bug
The config parser inconsistently throws an unexpected "Missing equal sign" error for classes.

To Reproduce

  1. Execute configparse__ "class A {};" a few times.
  2. See error: [ERR] [L1|C12|file] Missing equal sign (=).
    The error's column is also inconsistent. I've seen 12, 13, 14, 15, 19 and 20.

Expected behavior
No error.

Screenshots
N/A

Additional context
N/A

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.