###################################################################### # # *** IMPORTANT *** : Please do not submit or publish any additions # or improvements to this or other files just yet. # These files will likely be open source. # However, details have not been worked out yet. # Please do not submit bug reports yet either. # This beta is a snap shot with many missing or # evolving pieces, so it is already expected that # certain things won't work as anticipated. # # Tcl.uc: This sample version of Tcl was done while browsing through # Wikipedia, as well as the introduction and tutorial for # Tcl found at www.tcl.tk . # www.tcl.tk/man/tcl8.4/TclCmd/Tcl.htm # www.beedub.com/book/2nd/tclintro.doc.html # # For use with uCalc Language Builder v ??? # # Code in this file originally written by: Daniel Corbier # Contact: support at ucalc.com # Date: ??? # # Revision: ??? Date: ??? By: ??? contact: ??? # Modifications: ???, ???, ??? # ###################################################################### Pass: 5 Include: uCalc.uc SyntaxArg: {subst} = Chr(22) ~~ # Invisible characters are set up as markers SyntaxArg: {group} = Chr(23) SyntaxArg: {command} = Chr(24) SyntaxArg: {marker} = Chr(25) SyntaxArg: {end} = Chr(26) Pattern: [\q] ~~ # Turns double quote ( " ) into ordinary character Pass: 1 ~~ # Grouping stage; runs a marker through the line to help group things Syntax: {Prog_Start} ::= {command} {marker} Syntax: {Prog_Start}{Line:'[^\\]+'}{LineCont:'\\$'} ::= ~Exec(uc_IsIncomplete(~t, True)) Syntax: {Prog_Start}{Line:'[^\\]+'}{LineCont:'\\$'}{cr} ::= {Prog_Start}{Line} Syntax: {Prog_Start} [{code+} ;] # {comment:'.*'} ::= {Prog_Start} {code} Syntax: {Prog_Start} > {Debug:'.*'} ::= ucExpand({q}{Prog_Start}{Debug}{q}) Syntax: {Prog_Start} >> {Debug:'.*'} ::= ucSteps({q}{Prog_Start}{Debug}{q}) Syntax: {Prog_Start} >>> {Debug:'.*'} ::= {Debug} Syntax: {marker} ::= Syntax: {marker} {other:'[^\[\r ;]+'} ::= {group}{other}{end}{marker} Syntax: {marker} ${varName:1}[({index})] ::= {group}${varName}{index:({index})}{end}{marker} PassOnce ~~ Syntax: {marker} { '"' | '{' | '[' } ::= ~Exec(uc_IsIncomplete(~t, True)) Syntax: {marker} '[' {cmdGroup} ']' ::= {group}[{cmdGroup}]{end}{marker} Syntax: {marker} '{' {curly$+} '}' ::= {q}{curly}{q}{marker} Syntax: {marker} '"' {quoted:'[^\q]+'} '"' ::= {group}{quoted}{end}{marker} Syntax: {marker} {space:' +'} ::= {space}{marker} Syntax: {command} {marker} [{code+}] { ; | {cr}} ::= {command} {marker} {code} Syntax: {command} {marker} {code+} { ; | {cr}} {other} ::= ~Exec{q}{Prog_Start} {code}{q} {Prog_Start} {other} Syntax: {command} {marker} # {comment:'.*'} ::= Syntax: [{command} {marker}] eval ::= {command} {marker} Syntax: '"' {quoted:'[^\q]+$'} ::= ~Eval(uc_IsIncomplete(~t, True)) SkipOver ~~ Syntax: '"' {quoted:'[^\q]+'} '"' SkipOver ~~ Syntax: {group}{thing:'[^{end}]+'}{end} Pass: 2 ~~ # Inserts {subst} marker inside each relevent group in preperation for substition PassOnce ~~ Syntax: {group}{text:'[^{end}]+'}{end} ::= {group}{subst}{text}{end} Syntax: {group}{text:'[^{end}]+'}{end}{'{group}'} ::= {group}{text} Pass: 3 ~~ # Substitution stage Syntax: {subst} ::= Syntax: {subst}{end} ::= {end} Syntax: {subst}{text:'[^\[\$\{end}\\]+'} ::= {text}{subst} Syntax: {subst}'['{cmdGroup+}']' ::= ~Eval(eval {cmdGroup}){subst} Syntax: {subst}${var:1}[({index})] ::= {subst}[set {var}{index:({index})}] Syntax: {subst}\{char:'.'} ::= {char}{subst} Syntax: {subst}\{escape:'[abfnrtv]'} ::= ~Eval(Chr(Val(Escape_({q}{escape}{q})))){subst} Syntax: {subst}\{'x'}{hex:'..'} ::= ~Eval(Chr(BaseConvert('{hex}', 16))){subst} Syntax: {subst}{space:' +'} ::= {space}{subst} Pass: 4 ~~ # Strips group markers from commands names, and turns args into literals Syntax: {group}{text$+}{end} ::= {q}{text}{q} Syntax: {command}{group}{cmdGroup+}{end} ::= {command} {cmdGroup} Syntax: {command}{' *\x03'}{cmdGroup:'[^\x03]+'}{'\x03'} ::= {command} {cmdGroup} Pass: 5 ~~ # Command call stage; links Tcl commands to non-Tcl routines uCalc can interpret Syntax: Var: {VarName:1} ::= Var: {VarName} Syntax: IsDefined({var}) ::= (uCalc(-uc_GetItemData,'',uCalc(-uc_GetItemData,{var},0,uc_Handle,ucVariable), uc_Thread)== ~t) Syntax: Def: {from} {' *\:\:\='} {to:'.*'} ::= ~Define(Syntax: {command}{from} ::= {to}) Syntax: {command} ::= Def: {Other:1} [{etc:'.*'}] ::= WriteLn('invalid command name "{Other}"') Def: {Numeric:_Number} ::= {Numeric} Def: array {' *{q}set{q}'} {' *{q}'}{array:1}{'{q}'} {' *{q}'}{index:'[^ ]+'}{' +'} {value:'[^ {q}]+'} _ [{' +'}{more:'[^{q}]+'}]{'{q}'} ::= _ {command}set {q}{array}({index}){q} {q}{value}{q} {more: ; {command}array {q}set{q} {q}{array}{q} {q}{more}{q}}; '' Def: array {' *{q}size{q}'} {name:1} ::= ucEval({q1}uc_Count(UnQuote({name})){q1}) Def: concat [{first:1} [{more}]] ::= {first} {more: + ' ' + {command}concat {more}} Def: _expr {expr} ::= ucEval({expr}) Def: expr {expr} ::= ucEval('eval _expr ' + Chr(34) + {expr} + Chr(34)) Def: expr {' *{q}'}{itemA}{'{q}'} {' *{q}'}{itemB}{'{q}'} ::= {command}expr {q}{itemA} {itemB}{q} Def: for {start:1} {test:1} {next:1} {body:1} ::= ucEval('eval '+{start}); _ uc_Loop(Val(ucEval('eval expr '+{test})), ucEval('eval '+{body}+'; '+{next}), 1) Def: if {expr:1} [{' *{q}then{q}'}] {body:1} [[{' *{q}else{q}'}] {elseBody=''}] ::= _ iif(Val(ucEval('eval expr '+{expr})), ucEval('eval '+{body}), ucEval('eval '+{elseBody})) Def: incr {var:1} [{incr={q}1{q}}] ::= ucEval({q1}SetVar(_({var}), Str(Val(_({var}))+Val({incr}))){q1}); ucEval({var}) Def: puts [{channelId:1}] {string} ::= WriteLn({channelId: UnQuote({channelId}),} {string}) Def: puts {' *{q}-nonewline{q}'} [{channelId:1}] {string} ::= Write({channelId: UnQuote({channelId}),} {string}) Def: return {string} ::= ucEval({q1}{string}{q1}) Def: set {var:1} ::= ucEval({q1}_({var}){q1}) Def: set {var:1} {value:1} ::= _ ucEval({q1}IIf(IsDefined({var})==False, ucDefine({qq}Var:: String UnQuote({var}){qq})){q1}); _ ucEval({q1}SetVar(_({var}), {value}){q1}); {value} Def: set {quote:' +\x03'}{array~:1}({index}){quote2:'\x03'}::= {array}(ucEval('eval '+{q1}return {index}{q1})) Def: set {quote:' +\x03'}{array~:1}({index}){quote2:'\x03'} {value:1} ::= _ ucEval({q1}IIf(IsDefined({q}{array}{q})==False, ucDefine({q}Var: {array} As Table{q})){q1}); _ ucEval({q1}uc_Insert({array}, {q}{index}{q}, {value}){q1}); {value} Def: string {' *{q}index{q}'} {string:1} {index} ::= ucEval({q1}Chr(Asc({string}, Omni({index})+1)){q1}) Def: string {' *{q}length{q}'} {string:1} ::= ucEval({q1}Len({string}){q1}) Def: string {' *{q}range{q}'} {string:1} {first:1} {last:1} ::= _ uc_Peek(StrPtr({string})+Omni({first}), Omni({last})-Omni({first})+1) Def: while {test:1} {body:1} ::= uc_Loop(Val(ucEval('eval expr '+{test})), ucEval('eval '+{body}), 1) Syntax: DressArgsA([{txt:'[^ )]+'}[{space:' +'}{txt2:'[^)]+'}]]) ::= {txt2:DressArgsA}({txt}{txt2:,{txt2}}) Syntax: DressArgsB([{arg:1} [{moreArgs}]])::= {arg: {{arg}:1} DressArgsB({moreArgs})} Syntax: DressArgsC([{arg:1} [{moreArgs}]])::= {arg: {{arg}} {moreArgs:, DressArgsC({moreArgs})}} Syntax: {command}proc {' *{q}'}{name}{'{q}'} {' *{q}'}{args}{'{q}'} {body:1} ::= _ ucDefine({q1}Func: ~Expand({name} DressArgsA({args}) As String) = ucEval('eval '+{body}){q1}); _ ucExpand({q1}Def: ~Expand({name} DressArgsB({args}) ::= {name}(DressArgsC({args}))){q1}) Synonym: eq ==, ne <> Rename: '^' '**', 'Mod' '%', 'Sqr' 'Sqrt', 'And' '&', 'Or' '|', 'AndAlso' '&&', 'OrElse' '||' Execute: SetConst(True, 1) Execute: ucEval('eval array set Escape_ {a 7 b 8 f 12 n 10 r 13 t 9 v 11}') Execute: SetVar(Prompt_SingleLine, '% ') Execute: SetVar(Prompt_MultiLine, '') Execute: SetVar(REPL_Language, 'Tcl') Execute: SetVar(REPL_Startup, 'Startup.Tcl') Mode: Execute REPL_OR_FILE