#191 Parser accepts some declarations that it probably shouldn't

v2.5x
open
nobody
Internals (76)
5
2008-05-05
2008-05-05
gzarkadas
No

This does not produce erratic behavior in normal script operations and as such is a possibly low priority target (consistensy is the main reason for fixing), however since I have found it I make a report.

==============================================

Behaviors observed that are considered suspect to be buggy (reference scripts are appended to the end):

1. It is possible to declare a function in nested scopes (inside a function and a try...catch block) and use it everywhere in the script, ie with global visibility.

Ref.Scripts: #1, #2, #3

2. It is possible to declare an optional function argument as simply "int f"; the parser will accept it but the function body cannot access it of course (problem in whitespace handling).

Ref.Scripts: #5 (#4 is for the note below)

Note: It is possible also to declare function arguments as simply int, string, "clip", etc. They all become of the val (ie any) type with names int, string, clip, etc. and are accessible in the function body. This is perhaps a feature, but in any case I mention it FYI.

==============================================
Ref.Script #1
-------------
function test(int triger) {
s = "No Error"
a = 0
try {
function inner(int b) { return b }
a = (triger == 1 ? unknown : true) ? inner(2) : 0
try {
a = (triger == 2 ? unknown : true) ? inner(2) : 0
}
catch(msg) {
s = "Error in inner block"
}
}
catch(msg) {
s = "Error in outer block"
}
return s
}

s0 = test(0)
s1 = test(1)
s2 = test(2)
BlankClip(length=10, width=320, height=40)
StackVertical(last.Subtitle(s0), last.Subtitle(s1), last.Subtitle(s2), last.Subtitle(String(inner(4))))
==============================================
Ref.Script #2
-------------
function test(int triger) {
s = "No Error"
a = 0
try {
a = (triger == 1 ? unknown : true) ? 2 : 0
try {
a = (triger == 2 ? unknown : true) ? 4 : 0
}
catch(msg) {
function inner(int b) { return b }
s = "Error in inner block"
}
}
catch(msg) {
s = "Error in outer block"
}
return s
}

s0 = test(0)
s1 = test(1)
s2 = test(1)
BlankClip(length=10, width=320, height=40)
StackVertical(last.Subtitle(s0), last.Subtitle(s1), last.Subtitle(s2), last.Subtitle(String(inner(4))))
==============================================
Ref.Script #3
-------------
function test(int triger) {
s = "No Error"
function inner(int b) {
return b
}
a = 0
try {
a = (triger == 1 ? unknown : true) ? inner(2) : 0
try {
a = (triger == 2 ? unknown : true) ? inner(2) : 0
}
catch(msg) {
s = "Error in inner block"
}
}
catch(msg) {
s = "Error in outer block"
}
return s
}

s0 = test(0)
s1 = test(1)
s2 = test(2)
BlankClip(length=10, width=320, height=40)
StackVertical(last.Subtitle(s0), last.Subtitle(s1), last.Subtitle(s2), last.Subtitle(String(inner(4))))
==============================================
Ref.Script #4
-------------
function a(string, clip, "int") { return "a" }

BlankClip(length=10, width=400, height=100)
Subtitle(a("", last))
==============================================
Ref.Script #5
-------------
# parses with no errors!
function a(string b, clip c, "int f") { return b == "" ? c : b }

# throws error because f is not recognised
# function a(string b, clip c, "int f") { return b == "" ? String(f) : c }

# is 'int f' accesible ? --- NOP it isn't; see last line
function f(string b, clip c, "int f") { return Eval("int f") }

# throws error because b is not optional; ok
# function b(int, clip "c", string b) { return b + "what?" }

function b(int a, clip, "string") { return string }
function c(int a, clip, "string") { return clip.framecount }
function d(int a, clip, "string") { return clip }
function e(cat, dog, "house") { return defined(house) ? cat : dog }

BlankClip(length=10, width=400, height=180)
Subtitle(a("a", last, 4))
Subtitle(b(1, last, "say"), y=20) #ok returns "say"
Subtitle(String(b(1, last, 5)), y=40) #oops: now string is int!
Subtitle(String(c(1, last, 5)), y=60) #oops: does as expected
Subtitle(d(1, "My head will explode!", last), y=80) #oops: clip is treated as string

# therefore if one token T, it is assumed implicitly to be 'val T'
Subtitle(e("cat", "dog wins!"), y=100) # correct
Subtitle(e("cat wins!", "dog", true), y=120) # correct
# Subtitle(f("a", last, "surprise!"), y=140) # error, don't know what "int" means
==============================================

Discussion