public ktDelegateFunction(ktString Name, ktFunction_Double_Delegate Delegate) : base(Name, null, null, ktValue.Null) { m_Arguments = new ktList(); m_Arguments.Add(new ktValue("D", "double", kacTalk.Main.GetClass("double"), true, true)); m_Delegate = delegate(ktList Args) { if ((Args == null) || (Args.FirstNode == null) || (Args.FirstNode.Value == null)) { throw new ktError("Didn't get an argument for '" + Name + "'!", ktERR.MISSING); } //ktDebug.Log( "ktDF::DOUBLE(" +Args.FirstNode.Value.ToString() + ")" ); ktString S_In = new ktString(Args.FirstNode.Value.ToString()); double D_In = 0.0; double D_Out = 0.0; try { if (System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator == ",") { S_In.Replace(".", ",", true); } D_In = S_In.ToDouble(); } catch (Exception E) { if (E.GetType() == typeof(System.FormatException) && !S_In.IsEmpty()) { throw new ktError("ktDouble::CreateObject: Cant make '" + S_In + "' into an double", ktERR.WRONGTYPE); } } ktDebug.Log("D_In: " + D_In.ToString()); D_Out = Delegate(D_In); ktDebug.Log("D_Out: " + D_Out.ToString()); return new ktValue("return", "double", kacTalk.Main.MakeObjectOf("double", D_Out), true, true); }; }
// "Operations" // Escape a string /*(so it can be use as a ""plain" pattern")*/ public static ktString Escape(ktString Str) { Str.Replace("\\", "\\\\", true); Str.Replace("*", "\\*", true); Str.Replace("+", "\\+", true); Str.Replace("?", "\\?", true); Str.Replace("|", "\\|", true); Str.Replace("{", "\\{", true); Str.Replace("[", "\\[", true); Str.Replace("(", "\\)", true); Str.Replace(")", "\\)", true); Str.Replace("]", "\\]", true); Str.Replace("}", "\\}", true); Str.Replace("^", "\\^", true); Str.Replace("$", "\\$", true); Str.Replace(".", "\\.", true); Str.Replace("#", "\\#", true); Str.Replace("/", "\\/", true); return Str; }
/// <summary> /// Scan/Parse the script into tokens /// </summary> public bool Scan(ktString Script, ktString Name) { bool Ret = true; Script.Replace("\r\n", "\n",true); // Initiate the lineno. m_CurLine = 1; m_CharPos = 1; // .. and name m_Name = Name; if (m_Tokens != null) { m_Tokens.Clear(); m_Tokens = null; } // Init... ktString Line = new ktString(); int Pos = 0; Script.Trim(); ktRegEx RE = new ktRegEx(ktToken.Separators); // ... the block-stack if (m_BlockStack != null) { m_BlockStack.Clear(); m_BlockStack = null; } m_BlockStack = new ktList(); // ... the token-list if (m_Tokens != null) { m_Tokens.Clear(); m_Tokens = null; } m_Tokens = new ktList(); m_Tokens.Node = new ktNode("ktTStatement", new ktToken(ktTokenType.Statement, "", 0, 0)); // ... the token-stack if (m_TokenStack != null) { m_TokenStack.Clear(); m_TokenStack = null; } m_TokenStack = new ktList(); // ... the lines (??) if (m_Lines != null) { m_Lines.Clear(); m_Lines = null; } m_Lines = new ktList(); m_Lines.Node = new ktNode(Name, m_CurToken = new ktToken(ktTokenType.Program, Name, 0, 0)); // ... the line-stack if (m_LineStack != null) { m_LineStack.Clear(); m_LineStack = null; } m_LineStack = new ktList(); if (m_MainBlock == null) { m_MainBlock = new ktBlock(new ktList()); } else { if (m_MainBlock.Lines != null) { m_MainBlock.Lines.Clear(); } m_MainBlock.ClearKTSymbols(); } m_MainBlock.SetMain(this); m_BlockStack.Add("ktTBlock", m_MainBlock); /* In the "original scanner" (C++), we took one line (terminated by \n) * at a time and worked on, now we just go through the line. * And We hope that it will be much "leaner"! */ // Go on until the there's nothing left... while (!Script.IsEmpty()) { // Get the position for the next separator Pos = RE.Find(Script); // If there was none... if (Pos < 0) { // Take it to the end... Pos = Script.Len(); } else if (Pos == 0) { Pos++; } // Get the next "token" Line = Script.SubStr(0, Pos); // If it's the start of a comment if ((Line == "/") && (Script.StartsWith("//") || Script.StartsWith("/*"))) { Line = Script.SubStr(0, 2); Pos++; } else if ((Line == "*") && (Script.StartsWith("*/"))) { Line = "*/"; Pos++; } ReactOnToken(Line, m_CurLine, ref m_CharPos); if (Line == "\n") { m_CurLine++; m_CharPos = 1; } else { m_CharPos += Line.Len(); } // Remove the "token", we just worked on... Script.Remove(0, Pos); } #if ParseDebug || DebugXML ktDebug.Log("XML111111:"); ktDebug.Log(ktXML.FromList(m_TokenStack).AsXML()); ktDebug.Log("=================="); ktDebug.Log(ktXML.FromList(m_Tokens).AsXML()); #endif if (!m_Tokens.IsEmpty()) { if (m_AllowMissingEOL) { ((ktToken)m_Tokens.Node.Value).Type = ktTokenType.Line; ((ktToken)m_Tokens.Node.Value).Name = m_Tokens.Node.Name = "ktTLine"; m_LineStack.AddList(m_Tokens); m_Tokens = null; } else { throw new ktError("Expected a ktTEOL at line " + m_CurLine.ToString() + " but didn't find one!", ktERR.MISSING); } } if (m_BlockStack.Count > 1) { throw new ktError("Expecting ktTEOB (}) at " + m_CharPos.ToString() + ", line " + m_CurLine.ToString() + ".", ktERR.MISSING); } //ktToken.OnlyExportValue = false; //ktDebug.Log( m_LineStack.Get_R( ) ); //ktToken.OnlyExportValue = false; #if ParseDebug || DebugXML ktDebug.Log( "XML:" ); ktDebug.Log( ktXML.FromList(m_LineStack).AsXML() ); ktDebug.Log( "==================" ); ktDebug.Log( ktXML.FromList(m_Lines).AsXML() ); #endif /* ktDebug.Log( "?+++++\n" + m_Tokens.Get_R( "\t", true ) ); ktDebug.Log( "?+++++\n" + m_CurToken.Export if (m_CurToken != null) { if (m_CurToken.Type == ktTokenType.List) { throw new ktError( "Expected a ktTEndPar at line " + m_CurLine.ToString() + " but didn't find one!", ktERR.MISSING ); } else if (m_CurToken.Type == ktTokenType.String) { throw new ktError( "Expected a ktTStringQuot at line " + m_CurLine.ToString() + " but didn't find one!", ktERR.MISSING ); } else if (m_CurToken.Type == ktTokenType.Block) { throw new ktError( "Expected a ktTEndOfBlock at line " + m_CurLine.ToString() + " but didn't find one!", ktERR.MISSING ); } } else if ((m_Tokens != null) && (!m_Tokens.IsEmpty())) { throw new ktError( "Expected a ktTEOL at line " + m_CurLine.ToString() + " but didn't find one!", ktERR.MISSING ); } */ // MakeATree( ); // MakeAOpTree( ); if ((m_BlockStack == null) || (m_BlockStack.IsEmpty())) { return Ret; } ktBlock Block = (ktBlock)(m_BlockStack.Pop().Node.Value); #if ParseDebug ktDebug.Log( "BLOCK1:" + ktXML.FromList(Block.Lines).AsXML() );r #endif MakeATree(); #if ParseDebug ktDebug.Log("BLOCK2:" + ktXML.FromList(m_Lines).AsXML()); #endif Block.Lines = MakeAOpTree(); m_LineStack.Clear(); m_LineStack = null; // Add Current "statement"/"post" to the block and theń switch them //Temp.AddList( m_Tokens ); //m_Tokens = Temp; #if ParseDebug ktDebug.Log( "BLOCK:" + ((Block == m_MainBlock) ? "MAIN":"NOT_MAIN") ); #endif /*ktList Temp = null; if (LastBlockLines == null) { throw new ktError( "No Last Block Lines!", ktERR.MISSING ); } LastBlockLines.Add( "ktTBlock", new ktToken( Block, m_CurToken.LineNo, m_CurToken.CharPos ) );*/ #if ParseDebug || DebugXML ktDebug.Log( "XML_After Tree:" + ktXML.FromList(Block.Lines).AsXML() ); ktDebug.Log( "XML_After Tree:" + Block.Lines.Get_R( "\t", true ) ); #endif //ktDebug.Log( m_Lines.Export() ); return Ret; }