Open dekay9001 opened 12 years ago
Indeed, the "." is optional (added by request afterwards) and identifier scopes are searched from the current scope, upwards. This is currently the intended behaviour. The compiler doesn't currently output any warnings, but I think I will add this as the first ever warning message: "Local label referred to without . prefix: did you mean '.foo'?" - unless you think it is critical enough to be an error?
The assemblers i used before would only refer to a local label if it has the . prefix, which is why i have this issue multiple times in my code. I think local labels should be independent from global ones. The . prefix should just be a short form of - in this case - "start.foo":
; jumps to .foo, then calls foo :start set pc, .foo ; relates to :start.foo :.foo ; start.foo jsr foo ; relates to :foo sub pc, 1
:foo set pc, pop
I can't picture a situation where a local label would have the same name as a global one: local labels are things like not_found
, test_failed
, loop
- something specific and local I would have thought? I'm not sure I want to exclude a whole syntax possibility. Can you give me a good example of a good label name that makes sense as both a local and global please? Just want to make sure it's the best thing for everyone :)
After thinking about this, i'd say a warning message is probably the best, if it is common practice to use local labels without . prefix. I think it is good programming style to only refer to local labels with it, but i would also like to know how others think about it.
For an example I have multiple functions in my code that return a value that indicate what actions should be executed. Those actions mostly have each a subroutine with completely different parameters, so I have to jump to a local label which used to have the same name as the subroutines being called. I'm fixing this with s_ prefixes now.
:executeAction ; executes an action according to the value in a ifg a, 2 set pc, .error
; a: value between 0-2 set pc, [a+.switch] :.switch dat .s_refreshScreen, .s_refreshRow, .end
:.s_refreshScreen jsr refreshScreen ; call the subroutine set pc, .end
:.s_refreshRow set a, [current_row] jsr refreshRow ; call the subroutine set pc, .end
:.error set a, .str_invalidParam jsr assert
:.end set pc, pop :.str_invalidParam dat "Invalid parameter."
; --------------------------------------------------------- ; some dummy functions
:current_row dat 5
:assert sub pc, 1 :refreshScreen set pc, pop :refreshRow set pc, pop
this goes into an infinite loop spamming the stack with return addresses
:start
; local label .foo :.foo jsr foo ; jumps to :.foo(local) even though the "." is missing sub pc, 1 ; freeze
; subroutine foo :foo set pc, pop