theratioproject/simple

Building a better debugging module.

Youngestdev opened this issue ยท 12 comments

Well, if you've been following this repo, you'll find out we've been improving SIMPLE day by day.

In this project, we'll build/improve the existing debugging module because the current code displays the given code and doesn't debug in anyways.

Current code:

module simple.debugging
 
block throw(value)
	display value 
	__exit__

The future module will focus on tracking bugs in large scale apps without having to hard-find them.

@Thecarisma , you haven't given updates yet.

throw(errorvalue)

The throw() block is efficient now
A simple error can be thrown from any where in the program by calling the throw(errorvalue) block which is a block available in the Throw.sim file in the simple/debugging module therefore to use the throw(errorvalue) the Throw.sim file has to be called

call "simple/debugging/Throw.sim"

the throw(errorvalue) block is simply

block throw(errorvalue)
	if errorvalue = "" {
		errorvalue = "Unknown Error Occur"
	}
	__throw(errorvalue)
	if isLinux() {
		@ crlf
	}
	__exit__

which will give error in the follow format

Line 24 -> Unknown Error Occur
         at throw() in file Throw.sim
         at line 40 at three() in file debugging.sim
         at line 37 at two() in file debugging.sim
         at line 34 at one() in file debugging.sim
         at line 29 at main() in file debugging.sim
         at line 21 in file debugging.sim

The __throw(errorvalue) is a delegate block to the *void error_throw(void pointer) in core_dynamic_module dynamic module calling it directly is possible but not as safe as calling the wrapper block throw(errorvalue)

Great ๐ŸŽ‰

throwOnly(errorvalue)

Error tolerance is an encouraged feature in simple-lang therefore using the throw(errorvalue) is not error tolerant as it exit the program after displaying the error detail to counter this we have the throwOnly(errorvalue) block which is very error tolerant and does not exit the program after displaying the error

block throwOnly(errorvalue)
	if errorvalue = "" {
		errorvalue = "Unknown Error Occur"
	}
	__throw(errorvalue)
	if isLinux() {
		@ crlf
	}

It definitely far from safe as the reason why it is thrown is defied as the error will be carried along to another throwOnly() statement because the error will still be active. so to prevent a very erroneous program the @block throw(errorvalue) should be called instead.

this block is also available in the Throw.sim file in the simple/debugging module

stackTrace()

A list that returns all the lines, blocks called in all the imported file from the beginning of the program to the point where the block stackTrace() is called. The block is located in the simple/debugging directory and call be used by calling the debug file

call "simple/debugging/Debug.sim"
...
display stackTrace() 
...

an example result of the code above will be

at line 26 in __stack_trace at stackTrace() in file Debug.sim
at line 60 at four() in file debugging.sim
at line 33 at main() in file debugging.sim
at line 22 in file debugging.sim

the number of item in the stackTrace list depends on the position that is is being called from. This block can be used to create custom error and decision on error base on the programmer want.
The stackTrace() block is simply

block stackTrace()
	stackTrace = __stack_trace()
	if getTypeLength(stackTrace) == 0 {
			return throw(__STACK_TRACE_ERROR)
	}
	return stackTrace

The stack trace list can never be empty if empty then an __STACK_TRACE_ERROR is thrown. The value of __STACK_TRACE_ERROR is

__STACK_TRACE_ERROR = "Stack Trace cannot be empty error with the simple-lang Virtual Machine"

The __stack_trace() is a delegate to the C function *void error_stack_trace(void pointer) in the core_dynamic_module dynamic module

Bravo !!. This would be useful in try..catch blocks ! e.g

a = 10
try {
if ( a < 10 )
   @ a
else
   @ a
end
catch(err)
throw(err)
}

? is now erroneous replaces with @
if you catch an error it because the error is already thrown

Warn()

Show warning in your program if the program is executed along with the -w or --warning flag. Warning should not be destructive in a program i.e a warning should simply be a plain info of a way to do it better or what you have made better while a bad thing was to occur. If the warning is an information that could break the program it should be throw instead

call "simple/debugging/Debug.sim"
...
warn("This is a warning you see this if executed with -w") 
...

Then executed with the -w or --warning flag to see the warning
$ simple -w debugging.sim

result

Warning : This is a warning you see this if executed with -w

The warn(warnmessage) block is simply

block warn(warnmessage)
	if warnmessage == "" {
		return 
	}
	__warn(crlf+"Warning : "+warnmessage+crlf)

No warning will be displayed if simple vm is not sent the -w or --warning flag

assert()

Check and confirm whether the value sent as parameter is true. The value can be a statements e.g assert(( 2 > 4 && 5 < 9)), it can be a single variable e.g assert(false) it can be a block that return an evaluation e.g assert(getEval()) . If the value is not a number then an error is throw also if the value is not evaluated to true a evaluation fail error is also thrown

e.g

assert("string not assert able") # not number #fails 
assert((true == false)) # assert to false #fails
assert((1 > -300)) #assert to true #pass

The debugging module is efficient enough for now. so this issue can be close if satisfied
@Youngestdev please review

Great progress @Thecarisma . Well, for now, the issue will be closed and moved to completed
Other forms of error throwing techniques will/might be introduced in the later future.
Cheers ๐ŸŽ‰