* { font-family: Consolas, Lucida Console, Courier New; font-size: 100%; }
h1 { font-size: 150%; }
td.linenos { background-color: #f0f0f0; padding-right: 10px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
pre { line-height: 100%; width: 100%; }
.highlight span { width: 100%; display:-moz-inline-stack; display:inline-block; zoom:1; *display:inline; }
body { background: #ffffff; }
body .c { color: #999988; font-style: italic } /* Comment */
body .err { color: #a61717; background-color: #e3d2d2 } /* Error */
body .k { font-weight: bold } /* Keyword */
body .o { font-weight: bold } /* Operator */
body .cm { color: #999988; font-style: italic } /* Comment.Multiline */
body .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
body .c1 { color: #999988; font-style: italic } /* Comment.Single */
body .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
body .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
body .ge { font-style: italic } /* Generic.Emph */
body .gr { color: #aa0000 } /* Generic.Error */
body .gh { color: #999999 } /* Generic.Heading */
body .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
body .go { color: #888888 } /* Generic.Output */
body .gp { color: #555555 } /* Generic.Prompt */
body .gs { font-weight: bold } /* Generic.Strong */
body .gu { color: #aaaaaa } /* Generic.Subheading */
body .gt { color: #aa0000 } /* Generic.Traceback */
body .kc { font-weight: bold } /* Keyword.Constant */
body .kd { font-weight: bold } /* Keyword.Declaration */
body .kp { font-weight: bold } /* Keyword.Pseudo */
body .kr { font-weight: bold } /* Keyword.Reserved */
body .kt { color: #445588; font-weight: bold } /* Keyword.Type */
body .m { color: #009999 } /* Literal.Number */
body .s { color: #bb8844 } /* Literal.String */
body .na { color: #008080 } /* Name.Attribute */
body .nb { color: #999999 } /* Name.Builtin */
body .nc { color: #445588; font-weight: bold } /* Name.Class */
body .no { color: #008080 } /* Name.Constant */
body .ni { color: #800080 } /* Name.Entity */
body .ne { color: #990000; font-weight: bold } /* Name.Exception */
body .nf { color: #990000; font-weight: bold } /* Name.Function */
body .nn { color: #555555 } /* Name.Namespace */
body .nt { color: #000080 } /* Name.Tag */
body .nv { color: #008080 } /* Name.Variable */
body .ow { font-weight: bold } /* Operator.Word */
body .w { color: #bbbbbb } /* Text.Whitespace */
body .mf { color: #009999 } /* Literal.Number.Float */
body .mh { color: #009999 } /* Literal.Number.Hex */
body .mi { color: #009999 } /* Literal.Number.Integer */
body .mo { color: #009999 } /* Literal.Number.Oct */
body .sb { color: #bb8844 } /* Literal.String.Backtick */
body .sc { color: #bb8844 } /* Literal.String.Char */
body .sd { color: #bb8844 } /* Literal.String.Doc */
body .s2 { color: #bb8844 } /* Literal.String.Double */
body .se { color: #bb8844 } /* Literal.String.Escape */
body .sh { color: #bb8844 } /* Literal.String.Heredoc */
body .si { color: #bb8844 } /* Literal.String.Interpol */
body .sx { color: #bb8844 } /* Literal.String.Other */
body .sr { color: #808000 } /* Literal.String.Regex */
body .s1 { color: #bb8844 } /* Literal.String.Single */
body .ss { color: #bb8844 } /* Literal.String.Symbol */
body .bp { color: #999999 } /* Name.Builtin.Pseudo */
body .vc { color: #008080 } /* Name.Variable.Class */
body .vg { color: #008080 } /* Name.Variable.Global */
body .vi { color: #008080 } /* Name.Variable.Instance */
body .il { color: #009999 } /* Literal.Number.Integer.Long */
Info
Revision:3296
Author:victor
Date:2008-06-05 01:21:16 +0300 (Thu, 05 Jun 2008)
Comment:NXSL arrays - syntax fully implemented, some work on execution
Changes
U trunk/include/nxsl.h
U trunk/include/nxsl_classes.h
A trunk/src/client/console/nxmc/rc/nxmc.ico
U trunk/src/libnxsl/Makefile.am
A trunk/src/libnxsl/array.cpp
U trunk/src/libnxsl/libnxsl.dsp
U trunk/src/libnxsl/libnxsl.h
U trunk/src/libnxsl/parser.l
U trunk/src/libnxsl/parser.y
U trunk/src/libnxsl/program.cpp
U trunk/src/libnxsl/value.cpp
U trunk/src/nxcptest/nxcptest.cpp
Diff
Modified: trunk/include/nxsl.h
===================================================================
--- trunk/include/nxsl.h 2008-06-04 17:55:09 UTC (rev 3295)
+++ trunk/include/nxsl.h 2008-06-04 22:21:16 UTC (rev 3296)
@@ -67,6 +67,7 @@
#define NXSL_ERR_NOT_INTEGER 19
#define NXSL_ERR_INVALID_OBJECT_OPERATION 20
#define NXSL_ERR_BAD_CLASS 21
+#define NXSL_ERR_VARIABLE_ALREADY_EXIST 22
//
Modified: trunk/include/nxsl_classes.h
===================================================================
--- trunk/include/nxsl_classes.h 2008-06-04 17:55:09 UTC (rev 3295)
+++ trunk/include/nxsl_classes.h 2008-06-04 22:21:16 UTC (rev 3296)
@@ -41,12 +41,13 @@
#define NXSL_DT_NULL 0
#define NXSL_DT_OBJECT 1
-#define NXSL_DT_STRING 2
-#define NXSL_DT_REAL 3
-#define NXSL_DT_INT32 4
-#define NXSL_DT_INT64 5
-#define NXSL_DT_UINT32 6
-#define NXSL_DT_UINT64 7
+#define NXSL_DT_ARRAY 2
+#define NXSL_DT_STRING 3
+#define NXSL_DT_REAL 4
+#define NXSL_DT_INT32 5
+#define NXSL_DT_INT64 6
+#define NXSL_DT_UINT32 7
+#define NXSL_DT_UINT64 8
//
@@ -119,6 +120,30 @@
//
+// Array
+//
+
+class LIBNXSL_EXPORTABLE NXSL_Array
+{
+private:
+ int m_refCount;
+ NXSL_Value **m_data;
+
+public:
+ NXSL_Array();
+ NXSL_Array(NXSL_Array *src);
+ ~NXSL_Array();
+
+ void IncRefCount() { m_refCount++; }
+ void DecRefCount() { m_refCount--; }
+ BOOL IsUnused() { return m_refCount < 1; }
+
+ void Set(int index, NXSL_Value *value);
+ NXSL_Value *Get(int index);
+};
+
+
+//
// Variable or constant value
//
@@ -137,6 +162,7 @@
QWORD uInt64;
double dReal;
NXSL_Object *pObject;
+ NXSL_Array *pArray;
} m_value;
void UpdateNumber(void);
@@ -153,6 +179,7 @@
NXSL_Value(void);
NXSL_Value(const NXSL_Value *);
NXSL_Value(NXSL_Object *pObject);
+ NXSL_Value(NXSL_Array *pArray);
NXSL_Value(LONG nValue);
NXSL_Value(INT64 nValue);
NXSL_Value(DWORD uValue);
@@ -169,6 +196,7 @@
BOOL IsNull(void) { return (m_nDataType == NXSL_DT_NULL); }
BOOL IsObject(void) { return (m_nDataType == NXSL_DT_OBJECT); }
+ BOOL IsArray(void) { return (m_nDataType == NXSL_DT_ARRAY); }
BOOL IsString(void) { return (m_nDataType >= NXSL_DT_STRING); }
BOOL IsNumeric(void) { return (m_nDataType > NXSL_DT_STRING); }
BOOL IsReal(void) { return (m_nDataType == NXSL_DT_REAL); }
@@ -185,6 +213,7 @@
QWORD GetValueAsUInt64(void);
double GetValueAsReal(void);
NXSL_Object *GetValueAsObject(void) { return (m_nDataType == NXSL_DT_OBJECT) ? m_value.pObject : NULL; }
+ NXSL_Array *GetValueAsArray(void) { return (m_nDataType == NXSL_DT_ARRAY) ? m_value.pArray : NULL; }
void Concatenate(char *pszString, DWORD dwLen);
@@ -400,6 +429,7 @@
NXSL_Value *MatchRegexp(NXSL_Value *pValue, NXSL_Value *pRegexp, BOOL bIgnoreCase);
NXSL_Variable *FindOrCreateVariable(TCHAR *pszName);
+ NXSL_Variable *CreateVariable(TCHAR *pszName);
DWORD GetFunctionAddress(char *pszName);
void RelocateCode(DWORD dwStartOffset, DWORD dwLen, DWORD dwShift);
Property changes on: trunk/src/client/console/nxmc/rc/nxmc.ico
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Modified: trunk/src/libnxsl/Makefile.am
===================================================================
--- trunk/src/libnxsl/Makefile.am 2008-06-04 17:55:09 UTC (rev 3295)
+++ trunk/src/libnxsl/Makefile.am 2008-06-04 22:21:16 UTC (rev 3296)
@@ -1,7 +1,7 @@
INCLUDES=-I_at_top_srcdir@/include
lib_LTLIBRARIES = libnxsl.la
-libnxsl_la_SOURCES = lex.yy.cpp parser.tab.cpp class.cpp compiler.cpp \
+libnxsl_la_SOURCES = lex.yy.cpp parser.tab.cpp array.cpp class.cpp compiler.cpp \
env.cpp functions.cpp instruction.cpp lexer.cpp \
library.cpp main.cpp program.cpp stack.cpp value.cpp \
variable.cpp
Added: trunk/src/libnxsl/array.cpp
===================================================================
--- trunk/src/libnxsl/array.cpp (rev 0)
+++ trunk/src/libnxsl/array.cpp 2008-06-04 22:21:16 UTC (rev 3296)
@@ -0,0 +1,48 @@
+/*
+** NetXMS - Network Management System
+** NetXMS Scripting Language Interpreter
+** Copyright (C) 2005, 2006, 2007, 2008 Victor Kirhenshtein
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+** File: array.cpp
+**
+**/
+
+#include "libnxsl.h"
+
+
+//
+// Array constructors
+//
+
+NXSL_Array::NXSL_Array()
+{
+ m_refCount = 0;
+}
+
+NXSL_Array::NXSL_Array(NXSL_Array *src)
+{
+ m_refCount = 0;
+}
+
+
+//
+// Array destructor
+//
+
+NXSL_Array::~NXSL_Array()
+{
+}
Modified: trunk/src/libnxsl/libnxsl.dsp
===================================================================
--- trunk/src/libnxsl/libnxsl.dsp 2008-06-04 17:55:09 UTC (rev 3295)
+++ trunk/src/libnxsl/libnxsl.dsp 2008-06-04 22:21:16 UTC (rev 3296)
@@ -174,6 +174,10 @@
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
+SOURCE=.\array.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\class.cpp
# End Source File
# Begin Source File
Modified: trunk/src/libnxsl/libnxsl.h
===================================================================
--- trunk/src/libnxsl/libnxsl.h 2008-06-04 17:55:09 UTC (rev 3295)
+++ trunk/src/libnxsl/libnxsl.h 2008-06-04 22:21:16 UTC (rev 3296)
@@ -101,8 +101,10 @@
#define OPCODE_ILIKE 44
#define OPCODE_MATCH 45
#define OPCODE_IMATCH 46
-#define OPCODE_CASE 47
-#define OPCODE_ARRAY 48
+#define OPCODE_CASE 47
+#define OPCODE_ARRAY 48
+#define OPCODE_GET_ELEMENT 49
+#define OPCODE_SET_ELEMENT 50
//
Modified: trunk/src/libnxsl/parser.l
===================================================================
--- trunk/src/libnxsl/parser.l 2008-06-04 17:55:09 UTC (rev 3295)
+++ trunk/src/libnxsl/parser.l 2008-06-04 22:21:16 UTC (rev 3296)
@@ -48,6 +48,7 @@
<INITIAL>"match" return T_MATCH;
<INITIAL>"NULL" return T_NULL;
<INITIAL>"print" return T_PRINT;
+<INITIAL>"println" return T_PRINTLN;
<INITIAL>"real" return T_TYPE_REAL;
<INITIAL>"return" return T_RETURN;
<INITIAL>"string" return T_TYPE_STRING;
@@ -114,6 +115,8 @@
<INITIAL>"<" return '<';
<INITIAL>">" return '>';
<INITIAL>"?" return '?';
+<INITIAL>"[" return '[';
+<INITIAL>"]" return ']';
<INITIAL>"/*" { yyextra->m_nCommentLevel = 1; BEGIN COMMENT; }
<INITIAL>\" { yyextra->m_nStrSize = 0; BEGIN STR; }
Modified: trunk/src/libnxsl/parser.y
===================================================================
--- trunk/src/libnxsl/parser.y 2008-06-04 17:55:09 UTC (rev 3295)
+++ trunk/src/libnxsl/parser.y 2008-06-04 22:21:16 UTC (rev 3296)
@@ -48,6 +48,7 @@
%token T_IF
%token T_NULL
%token T_PRINT
+%token T_PRINTLN
%token T_RETURN
%token T_SUB
%token T_SWITCH
@@ -84,7 +85,7 @@
%left '+' '-'
%left '*' '/' '%'
%right T_INC T_DEC '!' '~' NEGATE
-%left T_POST_INC T_POST_DEC T_REF
+%left T_POST_INC T_POST_DEC T_REF '[' ']'
%type <pConstant> Constant
%type <valStr> AnyIdentifier
@@ -206,6 +207,14 @@
{
pScript->AddInstruction(new NXSL_Instruction(pLexer->GetCurrLine(), OPCODE_SET, $1));
}
+| Expression '[' Expression ']' '=' Expression
+{
+ pScript->AddInstruction(new NXSL_Instruction(pLexer->GetCurrLine(), OPCODE_SET_ELEMENT));
+}
+| Expression '[' Expression ']'
+{
+ pScript->AddInstruction(new NXSL_Instruction(pLexer->GetCurrLine(), OPCODE_GET_ELEMENT));
+}
| Expression T_REF T_IDENTIFIER
{
pScript->AddInstruction(new NXSL_Instruction(pLexer->GetCurrLine(), OPCODE_REFERENCE, $3));
@@ -395,7 +404,8 @@
;
BuiltinStatement:
- SimpleStatement ';'
+ SimpleStatement ';'
+| PrintlnStatement
| IfStatement
| DoStatement
| WhileStatement
@@ -453,7 +463,21 @@
| T_PRINT
{
$$ = new NXSL_Instruction(pLexer->GetCurrLine(), OPCODE_PRINT);
-}
+}
+;
+
+PrintlnStatement:
+ T_PRINTLN Expression ';'
+{
+ pScript->AddInstruction(new NXSL_Instruction(pLexer->GetCurrLine(), OPCODE_PUSH_CONSTANT, new NXSL_Value(_T("\n"))));
+ pScript->AddInstruction(new NXSL_Instruction(pLexer->GetCurrLine(), OPCODE_CONCAT));
+ pScript->AddInstruction(new NXSL_Instruction(pLexer->GetCurrLine(), OPCODE_PRINT));
+}
+| T_PRINTLN ';'
+{
+ pScript->AddInstruction(new NXSL_Instruction(pLexer->GetCurrLine(), OPCODE_PUSH_CONSTANT, new NXSL_Value(_T("\n"))));
+ pScript->AddInstruction(new NXSL_Instruction(pLexer->GetCurrLine(), OPCODE_PRINT));
+}
;
IfStatement:
Modified: trunk/src/libnxsl/program.cpp
===================================================================
--- trunk/src/libnxsl/program.cpp 2008-06-04 17:55:09 UTC (rev 3295)
+++ trunk/src/libnxsl/program.cpp 2008-06-04 22:21:16 UTC (rev 3296)
@@ -33,7 +33,7 @@
// Constants
//
-#define MAX_ERROR_NUMBER 21
+#define MAX_ERROR_NUMBER 22
#define CONTROL_STACK_LIMIT 32768
@@ -53,7 +53,7 @@
"BIND", "INC", "DEC", "NEG", "NOT",
"BITNOT", "CAST", "REF", "INCP", "DECP",
"JNZ", "LIKE", "ILIKE", "MATCH",
- "IMATCH", "CASE", "ARRAY"
+ "IMATCH", "CASE", "ARRAY", "EGET", "ESET"
};
@@ -83,7 +83,8 @@
_T("Invalid regular expression"),
_T("Function or operation argument is not a whole number"),
_T("Invalid operation on object"),
- _T("Bad (or incompatible) object class")
+ _T("Bad (or incompatible) object class"),
+ _T("Variable already exist")
};
@@ -532,6 +533,28 @@
//
+// Create variable if it does not exist, otherwise return NULL
+//
+
+NXSL_Variable *NXSL_Program::CreateVariable(TCHAR *pszName)
+{
+ NXSL_Variable *pVar = NULL;
+
+ if (m_pConstants->Find(pszName) == NULL)
+ {
+ if (m_pGlobals->Find(pszName) == NULL)
+ {
+ if (m_pLocals->Find(pszName) == NULL)
+ {
+ pVar = m_pLocals->Create(pszName);
+ }
+ }
+ }
+ return pVar;
+}
+
+
+//
// Execute single instruction
//
@@ -560,13 +583,31 @@
pValue = (NXSL_Value *)m_pDataStack->Peek();
if (pValue != NULL)
{
- pVar->Set(new NXSL_Value(pValue));
+ if (pValue->IsArray())
+ {
+ pVar->Set(new NXSL_Value(new NXSL_Array(pValue->GetValueAsArray())));
+ }
+ else
+ {
+ pVar->Set(new NXSL_Value(pValue));
+ }
}
else
{
Error(NXSL_ERR_DATA_STACK_UNDERFLOW);
}
break;
+ case OPCODE_ARRAY:
+ pVar = CreateVariable(cp->m_operand.m_pszString);
+ if (pVar != NULL)
+ {
+ pVar->Set(new NXSL_Value(new NXSL_Array));
+ }
+ else
+ {
+ Error(NXSL_ERR_VARIABLE_ALREADY_EXIST);
+ }
+ break;
case OPCODE_CAST:
pValue = (NXSL_Value *)m_pDataStack->Peek();
if (pValue != NULL)
Modified: trunk/src/libnxsl/value.cpp
===================================================================
--- trunk/src/libnxsl/value.cpp 2008-06-04 17:55:09 UTC (rev 3295)
+++ trunk/src/libnxsl/value.cpp 2008-06-04 22:21:16 UTC (rev 3296)
@@ -1,7 +1,7 @@
/*
** NetXMS - Network Management System
** NetXMS Scripting Language Interpreter
-** Copyright (C) 2005, 2006 Victor Kirhenshtein
+** Copyright (C) 2005, 2006, 2007, 2008 Victor Kirhenshtein
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -103,6 +103,11 @@
{
m_value.pObject = new NXSL_Object(pValue->m_value.pObject);
}
+ else if (m_nDataType == NXSL_DT_ARRAY)
+ {
+ m_value.pArray = pValue->m_value.pArray;
+ m_value.pArray->IncRefCount();
+ }
else
{
memcpy(&m_value, &pValue->m_value, sizeof(m_value));
@@ -133,6 +138,15 @@
m_bStringIsValid = FALSE;
}
+NXSL_Value::NXSL_Value(NXSL_Array *pArray)
+{
+ m_nDataType = NXSL_DT_ARRAY;
+ m_value.pArray = pArray;
+ pArray->IncRefCount();
+ m_pszValStr = NULL;
+ m_bStringIsValid = FALSE;
+}
+
NXSL_Value::NXSL_Value(LONG nValue)
{
m_nDataType = NXSL_DT_INT32;
@@ -209,7 +223,15 @@
{
safe_free(m_pszValStr);
if (m_nDataType == NXSL_DT_OBJECT)
- delete m_value.pObject;
+ {
+ delete m_value.pObject;
+ }
+ else if (m_nDataType == NXSL_DT_ARRAY)
+ {
+ m_value.pArray->DecRefCount();
+ if (m_value.pArray->IsUnused())
+ delete m_value.pArray;
+ }
}
@@ -365,7 +387,7 @@
char *NXSL_Value::GetValueAsCString(void)
{
- if (IsNull() || IsObject())
+ if (IsNull() || IsObject() || IsArray())
return NULL;
if (!m_bStringIsValid)
@@ -380,7 +402,7 @@
char *NXSL_Value::GetValueAsString(DWORD *pdwLen)
{
- if (IsNull() || IsObject())
+ if (IsNull() || IsObject() || IsArray())
{
*pdwLen = 0;
return NULL;
Modified: trunk/src/nxcptest/nxcptest.cpp
===================================================================
--- trunk/src/nxcptest/nxcptest.cpp 2008-06-04 17:55:09 UTC (rev 3295)
+++ trunk/src/nxcptest/nxcptest.cpp 2008-06-04 22:21:16 UTC (rev 3296)
@@ -172,7 +172,7 @@
msg = new CSCPMessage(xml);
rawMsg = msg->CreateMessage();
delete msg;
- if (SendEx(hSocket, rawMsg, ntohl(rawMsg->dwSize), 0) != ntohl(rawMsg->dwSize))
+ if ((DWORD)SendEx(hSocket, rawMsg, ntohl(rawMsg->dwSize), 0) != ntohl(rawMsg->dwSize))
{
printf("Error sending message\n");
free(rawMsg);
Received on Thu Jun 05 2008 - 01:21:18 EEST
This archive was generated by hypermail 2.2.0 : Thu Jun 05 2008 - 01:18:45 EEST