###################################################################### # *** 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 Python was done while browsing through # the Python Language Reference at docs.python.org/reference # and the 3.2 tutorial at docs.python.org/tutorial and ... # # 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: 11 Include: uCalc.uc Include: List.uc Var: _TempList As Stack ~~ # For multiple-assignment Op: {x} // {y} := int(x/y) ~~ # Integer division Overwrite ~~ Func: REPL_Format(Result As String, t As Long) As String = _ IIf(REPL_LastValueType == String, _ IIf(InStr(Result, '"')>0 Or InStr(Result, "'")==0, "'"+Result+"'", '"'+Result+'"'), Result) Pattern: \q\q\q ~~ \q\q\q ~~ DataType: String ~~ Properties: ucQuotedText+ucLiteral Pattern: \'\'\' ~~ \'\'\' ~~ DataType: String ~~ Properties: ucQuotedText+ucLiteral Pattern: \[ ~~ \] ~~ DataType: Stack ~~ Address: @uc_Func_Populate_Stack ~~ Properties: ucCodeBlock Pattern: : ~~ Properties: ucStatementSep Func: _ErrorHandler(ErrorNumber, SymbolName As String, t) As Long = { IIf(ErrorNumber == uc_Err_Undefined_Identifier And uc_IsIncomplete(t) == False, WriteLn("name '" + SymbolName + "' is not defined")); IIf(ErrorNumber == uc_Err_Unbalanced_Quote, uc_IsIncomplete(t, True); 0) } ErrorHandler: _ErrorHandler(uCalc(uc_GetErrorNumber), uCalcStr(uc_GetSymbol), ~t) Var: _INDENT As Stack Func: CheckIndentation(Spaces, Code As String) As String = { ~Local(Var: Temp As String) ~Local(Var: Last_INDENT) SetVar(Last_INDENT, uc_ReadNum(_INDENT)); IIf(Spaces > Last_INDENT, uc_Push(_INDENT, Spaces); SetVar(Temp, ":" + Code)); IIf(Spaces == Last_INDENT, SetVar(Temp, ";" + Code)); IIf(Spaces < Last_INDENT, uc_Loop(Spaces < uc_ReadNum(_INDENT), uc_PopNum(_INDENT); SetVar(Temp, Temp+";"), 1); SetVar(Temp, Temp + Code) ); Temp } Func: _JoinLines(Line As String, t As Long) As String = { ~Local(Var: i) IIf(Right(Line, 1) == "\", uc_IsIncomplete(t, True)); uc_Loop(1, SetVar(i, InStr(Line, "\"+CrLf)); IIf(i>0, SetVar(Line, Left(Line, i-1) + Mid(Line, i+3))), i>0); Line } Pass: 1 ~~ ## Handles "_" for last value, and comments starting with # Syntax: _ ::= ~Eval(IIf(REPL_LastValueType == String, {q}REPL_LastValue{q}, REPL_LastValue)) Syntax: {Comment:"[ ]*#.*"}[{cr}] ::= SkipOver ~~ Syntax: {Prog_Start} Pass: 2 ~~ ## Line continuation char \ PassOnce ~~ Syntax: {Prog_Start}{Code:"[\x00-\xFF]+"} ::= {Prog_Start}~Eval(_JoinLines({q}{Code}{q}, ~t)) Pass: 3 ~~ ## Handles escapes within quoted strings Var: _EscapeSeq As Table Syntax: SetEsc:{' +'}{char:'.'}{ASCII:1}[{more:'.*'}]::=uc_Insert(_EscapeSeq,{q}{char}{q},{ASCII});{more: SetEsc: {more}} Execute: SetEsc: \ 92 ' 39 " 34 a 7 b 8 f 12 n 10 r 13 t 9 v 11 Syntax: {Text:"\'[^\'\r\\]*"}{'\\'}{Escape"[\\'\qabfnrtv]"} ::= {Text}'+Chr(~Eval(_EscapeSeq({q}{Escape}{q})))+' Syntax: {Text:'\q[^\q\r\\]*'}{'\\'}{Escape"[\\'\qabfnrtv]"} ::= {Text}"+Chr(~Eval(_EscapeSeq({q}{Escape}{q})))+" Pass: 4 ~~ ## Literal concatenate (Ex: "This " "that" --> "This that") Syntax: {String1:"\q[^\q]*\q"}[{"[ \r\n]+"}]{MoreText:"[\q\']"} ::= {String1}+{MoreText} Syntax: {String1:"\'[^\']*\'"}[{"[ \r\n]+"}]{MoreText:"[\q\']"} ::= {String1}+{MoreText} Pass: 5 ~~ ## Adds {Prog_End} (a non-text char) at the end of code block PassOnce ~~ Syntax: {Prog_Start}{All:"[\x00-\xFF]+"} ::= {Prog_Start}{All}{Prog_End} Pass: 6 ~~ ## Forces interpreter to ask for more when block of code is incomplete Syntax: : ::= ~Eval(uc_IsIncomplete(~t, True); ResetVariable(_INDENT); uc_Push(_INDENT, 0)) SkipOver ~~ Syntax: :{code~+}{cr}{Prog_End} Syntax: :{Prog_End} ::= ~Eval(uc_IsIncomplete(~t, True); ResetVariable(_INDENT); uc_Push(_INDENT, 0)) SkipOver ~~ Syntax: Var: {def:"[\x00-\xFF]+"} SkipOver ~~ Syntax: "[" [{a}]:[{b}] "]" Pass: 7 ~~ ## Transforms indented code into code blocks Syntax: {cr}[{indent:"[ ]+"}{code:".+"}] ::= ~Eval( CheckIndentation(Len("{indent}"), {q}{code}{q}) ) Syntax: :{cr}{indent:"[ ]+"}{code:".+"} ::= ~Eval( CheckIndentation(Len("{indent}"), {q}{code}{q}) ) SkipOver ~~ Syntax: :{code+}; SkipOver ~~ Syntax: Var: {def:"[\x00-\xFF]+"} Pass: 8 ~~ ## Handles variable assignments SkipOver ~~ Precedence: 1 ~~ Syntax: {code} ::= ~Expand({code}) Syntax: {variable} = {value} [{stop: }] ::= _ ~Exec(IIf(ucHandle('{variable}')==0, ucDefine('Var: {variable} As '+Type({value})))) _ SetVar({variable}, {value}) {stop} Syntax: {var1} = {varN>} = {value} ::= {var1} = {value}; {varN} = {value} SkipOver ~~ Syntax: ({arg1>}, {ArgN}) Syntax: {var1}, {varN~} = {value1}, {valueN>} ::= SetVar(_TempList, [{value1}, {valueN}]); SetMulti({var1}, {varN}) Syntax: SetMulti({var1} [, {varN}]) ::= {varN: SetMulti({varN});} ucEval({q}{var1} = ~Eval(uc_PopStr(_TempList)){q}) Pass: 9 ~~ ## Handles slicing Precedence: 100 Syntax: {x}"["{index}"]" ::= _ ~Eval(IIf(DataType({x})==String, "Mid({x}, {index} + 1*({index}>=0), 1)", "StackItemValue({x}, {index}+1)")) Syntax: {x}"["[{index=0}]:[{count=1E6}]"]" ::= _ ~Eval(IIf(DataType({x})==String,"Mid({x},{index}+1*({index}>=0), {count})", "StackSlice({x},{index}+1, {count})")) Syntax: {str}.strip([{chars=' '}]) ::= TrimAny({str}, {chars}) Syntax: {str}.upper() ::= UpperCase({str}) Syntax: {StackVar}.append({data}) ::= uc_Push({StackVar}, {data}) Syntax: {Prog_Start} ::= Syntax: {Prog_End} ::= Precedence: 10 Pass: 10 ~~ ## print() statement (python 3+) PassOnce ~~ Syntax: print({data+} [, sep={sep=' '}] [, end={end='{cr}'}]) ::= _ print({data}, sep={sep}, end={end}) Pass: 11 ~~ ## Misc (if, while, & everything else) Syntax: ::= Syntax: if {condition}: {code+} ::= IfElseIf({condition}, {code}) Syntax: while {condition}: {code+} ::= uc_Loop({condition}, {code}, 1) Syntax: print({data+}, sep={sep}, end={end}) ::= Write(Omni({data})+{end}) Syntax: print({data+}, {more+}, sep={sep}, end={end}) ::= _ Write(Omni({data})+{sep}); print({more}, sep={sep}, end={end}) ## Things mostly for the interpreter Execute: SetConst(True, 1) Execute: SetVar(Prompt_SingleLine, ">>> ") Execute: SetVar(Prompt_MultiLine, "... ") Execute: SetVar(REPL_Language, "Python") Execute: SetVar(List_Open, "["); SetVar(List_Close, "]") Mode: Execute REPL_OR_FILE