+
BinaryReader
|
diff --git a/doc/api/system-io.html b/doc/api/system-io.html
index 6e0241d232..f382e0663e 100644
--- a/doc/api/system-io.html
+++ b/doc/api/system-io.html
@@ -23,6 +23,224 @@
+
+
+
+
+
+
+
+
+
+abstract public class BaseTextReader
+
+
+
+
+
+-
+
Field Summary
+
+
+Modifier and Type |
+Field |
+
+
+
+
+TextBuilder |
+
+_output
+ |
+
+
+
+
+String |
+
+_newLineConstant
+ |
+
+
+
+
+IntNumber |
+
+_newLineLength
+ |
+
+
+
+
+
+
+-
+
Method Summary
+
+
+Modifier and Type |
+Method |
+
+
+
+
+String |
+
+readLine()
+
+ |
+
+
+
+
+WideString |
+
+readWideLine()
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+abstract public class BaseTextWriter
+
+
+
+
+
+-
+
Field Summary
+
+
+Modifier and Type |
+Field |
+
+
+
+
+TextBuilder |
+
+_buffer
+ |
+
+
+
+
+String |
+
+_newLineConstant
+ |
+
+
+
+
+IntNumber |
+
+_newLineLength
+ |
+
+
+
+
+
+
+-
+
Method Summary
+
+
+Modifier and Type |
+Method |
+
+
+
+
+ |
+
+write(String line)
+
+ |
+
+
+
+
+ |
+
+write(WideString line)
+
+ |
+
+
+
+
+ |
+
+writeLine(line)
+
+ |
+
+
+
+
+ |
+
+writeLine()
+
+ |
+
+
+
+
+
+
@@ -2254,12 +2472,18 @@ StreamWriter
+
+
-
@@ -2437,42 +2661,6 @@
TextReader
-
-
--
-
Field Summary
-
-
-Modifier and Type |
-Field |
-
-
-
-
-TextBuilder |
-
-_output
- |
-
-
-
-
-String |
-
-_newLineConstant
- |
-
-
-
-
-IntNumber |
-
-_newLineLength
- |
-
-
-
-
-
@@ -2539,7 +2727,7 @@
Method Summary
-String |
+abstract String
readLine()
@@ -2548,7 +2736,7 @@ Method Summary
|
-WideString |
+abstract WideString
readWideLine()
@@ -2585,12 +2773,18 @@ TextStreamReader
-
+
+
-
@@ -2784,42 +2978,6 @@
TextWriter
-
-
--
-
Field Summary
-
-
-Modifier and Type |
-Field |
-
-
-
-
-TextBuilder |
-
-_buffer
- |
-
-
-
-
-String |
-
-_newLineConstant
- |
-
-
-
-
-IntNumber |
-
-_newLineLength
- |
-
-
-
-
-
@@ -2887,34 +3045,34 @@
Method Summary
- |
+abstract
-writeLine(line)
+write(String line)
|
- |
+abstract
-write(String line)
+write(WideString line)
|
- |
+abstract
-write(WideString line)
+writeLine(line)
|
- |
+abstract
writeLine()
diff --git a/doc/api/system-summary.html b/doc/api/system-summary.html
index 42e64f56b2..d87eb28191 100644
--- a/doc/api/system-summary.html
+++ b/doc/api/system-summary.html
@@ -90,6 +90,15 @@
|
+BaseEnumerator
+ |
+
+
+abstract public class BaseEnumerator
+ |
+
+
+
BaseEnumerator<T1>
|
@@ -97,7 +106,7 @@
abstract public template BaseEnumerator<T1>
|
-
+
BaseExtender
|
@@ -106,7 +115,7 @@
public class BaseExtender
-
+
BaseIndexer
|
@@ -115,7 +124,7 @@
abstract public class BaseIndexer
-
+
BaseIndexer<T1>
|
@@ -124,7 +133,7 @@
abstract public template BaseIndexer<T1>
-
+
BaseLazyExpression
|
@@ -133,7 +142,7 @@
abstract public class BaseLazyExpression
-
+
BaseNumber
|
@@ -143,7 +152,7 @@
a base numeric value
-
+
BaseValue
|
@@ -153,7 +162,7 @@
a base value
-
+
BaseVariable
|
@@ -163,7 +172,7 @@
variable base class
-
+
BitArray
|
@@ -172,7 +181,7 @@
public class BitArray
-
+
BitArray32
|
@@ -181,7 +190,7 @@
public class BitArray32
-
+
BoolValue
|
@@ -191,7 +200,7 @@
a common boolean value
-
+
BoolValue#false
|
@@ -200,7 +209,7 @@
public singleton BoolValue#false
-
+
BoolValue#true
|
@@ -209,7 +218,7 @@
public singleton BoolValue#true
-
+
byteArrayConvertor
|
@@ -218,7 +227,7 @@
public singleton byteArrayConvertor
-
+
byteConvertor
|
@@ -227,7 +236,7 @@
public singleton byteConvertor
-
+
ByteNumber
|
@@ -237,7 +246,7 @@
an unsigned 8 bit integer
-
+
CallStack
|
@@ -247,7 +256,7 @@
A call stack
-
+
charConvertor
|
@@ -256,7 +265,7 @@
public singleton charConvertor
-
+
CharValue
|
@@ -266,7 +275,7 @@
An UTF-32 character symbol
-
+
ClassReference
|
@@ -275,7 +284,7 @@
public class ClassReference
-
+
Console
|
@@ -284,7 +293,7 @@
public class Console
-
+
COORD
|
@@ -293,7 +302,7 @@
public class COORD
-
+
CriticalException
|
@@ -302,7 +311,7 @@
public class CriticalException
-
+
DivisionByZeroException
|
@@ -311,7 +320,7 @@
public class DivisionByZeroException
-
+
Enumerable
|
@@ -320,7 +329,7 @@
abstract public class Enumerable
-
+
Enumerable<T1>
|
@@ -329,7 +338,7 @@
abstract public template Enumerable<T1>
-
+
Enumerator
|
@@ -339,7 +348,7 @@
An enumerator prototype
-
+
Enumerator<T1>
|
@@ -348,7 +357,7 @@
abstract public template Enumerator<T1>
-
+
Exception
|
@@ -358,7 +367,7 @@
A basic exception
-
+
Extension
|
@@ -367,7 +376,7 @@
public class Extension
-
+
ExtensionMessage
|
@@ -377,7 +386,7 @@
An extended message constant
-
+
ExtensionVariable
|
@@ -386,7 +395,7 @@
public class ExtensionVariable
-
+
FormatException
|
@@ -395,7 +404,7 @@
public class FormatException
-
+
Func
|
@@ -405,6 +414,15 @@
A base action
+
+
+Func<T1,T1,system'IntNumber>
+ |
+
+
+abstract public template Func<T1,T1,system'IntNumber>
+ |
+
Func<T1,T2>
diff --git a/doc/api/system-text-summary.html b/doc/api/system-text-summary.html
index 3de4a3e16b..7c2c149a85 100644
--- a/doc/api/system-text-summary.html
+++ b/doc/api/system-text-summary.html
@@ -53,6 +53,15 @@
|
+StringBuilder
+ |
+
+
+public class StringBuilder
+ |
+
+
+
TextBuilder
|
@@ -60,7 +69,7 @@
public class TextBuilder
|
-
+
UTF16Encoder
|
@@ -69,7 +78,7 @@
public singleton UTF16Encoder
-
+
UTF16Encoding
|
@@ -78,7 +87,7 @@
public singleton UTF16Encoding
-
+
UTF8Encoder
|
@@ -87,7 +96,7 @@
public singleton UTF8Encoder
-
+
UTF8Encoding
|
@@ -96,6 +105,15 @@
public singleton UTF8Encoding
+
+
+WideStringBuilder
+ |
+
+
+public class WideStringBuilder
+ |
+
WinEncoder
diff --git a/doc/api/system-text.html b/doc/api/system-text.html
index 0f188f1373..2a8ecec81d 100644
--- a/doc/api/system-text.html
+++ b/doc/api/system-text.html
@@ -126,6 +126,186 @@ Method Summary
+
+
+
+
+
+
+
+
+
+public class StringBuilder
+
+
+
+
+
+
+
+-
+
Constructor / Static Method Summary
+
+
+Modifier and Type |
+Constructor / Static Method |
+
+
+
+
+StringBuilder |
+
+constructor()
+
+ |
+
+
+
+
+
+
+-
+
Property Summary
+
+
+Modifier and Type |
+Property |
+
+
+
+
+get IntNumber |
+
+Length()
+ |
+
+
+
+
+get String |
+
+Value()
+ |
+
+
+
+
+
+
+
+
@@ -669,6 +849,15 @@ Method Summary
|
+ |
+
+toShortArray(CharValue ch, system'ShortNumber[] output, IntNumber outputIndex, ref IntNumber len)
+
+ |
+
+
+
+
IntNumber |
getCharCount(WideString s)
@@ -811,6 +1000,186 @@ Method Summary
+
+
+
+
+
+
+
+
+
+public class WideStringBuilder
+
+
+
+
+
+
+
+-
+
Constructor / Static Method Summary
+
+
+Modifier and Type |
+Constructor / Static Method |
+
+
+
+
+WideStringBuilder |
+
+constructor()
+
+ |
+
+
+
+
+
+
+-
+
Property Summary
+
+
+Modifier and Type |
+Property |
+
+
+
+
+get IntNumber |
+
+Length()
+ |
+
+
+
+
+get String |
+
+Value()
+ |
+
+
+
+
+
+
+
+
diff --git a/doc/api/system.html b/doc/api/system.html
index 1613f9e3b3..0ae92c1e94 100644
--- a/doc/api/system.html
+++ b/doc/api/system.html
@@ -373,6 +373,8 @@ Constructor / Static Method Summary
copy(T1[] target, T1[] source, IntNumber index, IntNumber length)
+
+Copies a subarray from source starting at index to target
|
|
@@ -382,6 +384,8 @@ Constructor / Static Method Summary
copyTo(T1[] target, T1[] source, IntNumber index, IntNumber length)
+
+Copies a source array to target at index
|
@@ -885,6 +889,89 @@ Method Summary
+
+
+
+
+
+
+
+
+
+abstract public class BaseEnumerator
+
+
+
+
+
+
+
+-
+
Method Summary
+
+
+Modifier and Type |
+Method |
+
+
+
+
+BoolValue |
+
+next()
+
+ |
+
+
+
+
+
+
@@ -5884,6 +5971,75 @@ Method Summary
+
+
+
+
+
+
+
+
+
+abstract public template Func<T1,T1,system'IntNumber>
+
+
+
+-
+system'Object
+-
+
+-
+system'Func<T1,T1,system'IntNumber>
+
+
+
+
+
+-
+
Conversion Summary
+
+
+Modifier and Type |
+Conversion Method |
+
+
+
+
+Func2 |
+
+cast()
+ |
+
+
+
+
+
+
+-
+
Method Summary
+
+
+Modifier and Type |
+Method |
+
+
+
+
+abstract IntNumber |
+
+function(T1 arg1, T1 arg2)
+
+ |
+
+
+
+
+
+
diff --git a/doc/tech/bytecode60.txt b/doc/tech/bytecode60.txt
index 7b4e83649a..072cb73f1d 100644
--- a/doc/tech/bytecode60.txt
+++ b/doc/tech/bytecode60.txt
@@ -132,7 +132,7 @@ ELENA byte codes (or ecodes)
xassign i - acc[i] := sp[0];
direct operation
- xfsave - double:[acc] := double:index
+ xfsave - double:[acc] := double:index
xget - acc[index] => acc
@@ -140,7 +140,7 @@ ELENA byte codes (or ecodes)
xlload - long:index := long:acc[index]
- xpeekne - acc <= COMP.EQ ? sp[0] : acc
+ xpeekeq - acc <= COMP.EQ ? sp[0] : acc
xset fp:i - fp[index + i] => acc
diff --git a/doc/todo.txt b/doc/todo.txt
index 2bc0e16c05..0e10f1b094 100644
--- a/doc/todo.txt
+++ b/doc/todo.txt
@@ -3,28 +3,106 @@ In development:
------
[development]
- ### EPIC: elena 6.0 - redux ###
+ ### EPIC: elena 6.2 ###
- === Iteration 23 ===
+ === Iteration 24 ===
--------------------------------------
- dev: #574,#265,#619,#637(bt tests (>=4), all bc tests)
+ dev: #574,#265,#619,#580
op: github action - create a draft release
- opt:pi under 6 sec
- maint:#620, #486, #506
+ opt:pi under 6 sec, #611, #602, #601, #586
+ maint:#486, #506, #650
exp: generate code templates - e.g. simple console app
- ide:linux simplest gui, vm debugger
- tools:elt64-cli
- prom:#635 on reddit;elena in nutshell every 1 week; post an article describing how to use distributed dictionary for test
- port:chat sample, elenavm / elt for linux, helloworld gui sample (button)
+ ide:vm debugger, #617, linux ide, linux debugger
+ tools:#618, #620
+ prom:#635 on reddit;elena in nutshell every 1 week; post an article about attributes (decorate a class, defining which operation is allowed)
+ port:elenavm / elt for linux, helloworld gui sample (button)
+ --------------------------------------
+ - #590 : functional test
+ - #620 : add out argument (a special case of Reference template), to indicate the variable must be assigned before the method exit
+ * #590 : vm : InjectProxyTypeLA
+ - #590 : implementing interface injection : strong interface
+ - #184 : linux simplest gui
+ - elt : nested call must not stop / start vm
+ - elt : fails after executing several times
+ - #99
+ - #98
+ - #97
+ - #79
+ - #637(bt tests (>=4), all bc tests)
+ - #69
+ - chat sample
+ --------------------------------------
- === Iteration 24 ===
+ === Iteration 25 ===
--------------------------------------
dev: async programming (instant messagange sample (chat) )
op:
opt:
- maint:
+ maint:#620
exp:
ide:
tools:
prom:
port:upndown
+
+ === Iteration 26 ===
+ --------------------------------------
+ dev:
+ op:
+ opt:
+ maint:
+ exp:
+ ide:
+ tools:
+ prom:
+ port:
+
+ ### EPIC: elena 6.3 ###
+
+ === Iteration 27 ===
+ --------------------------------------
+ dev:
+ op:
+ opt:
+ maint:
+ exp:
+ ide:
+ tools:
+ prom:
+ port:
+
+ === Iteration 28 ===
+ --------------------------------------
+ dev:
+ op:
+ opt:
+ maint:
+ exp:
+ ide:
+ tools:
+ prom:
+ port:
+
+ === Iteration 29 ===
+ --------------------------------------
+ dev:
+ op:
+ opt:
+ maint:
+ exp:
+ ide:
+ tools:
+ prom:
+ port:
+
+ === Iteration 30 ===
+ --------------------------------------
+ dev:
+ op:
+ opt:
+ maint:
+ exp:
+ ide:
+ tools:
+ prom:
+ port:
diff --git a/elenasrc3/common/streams.h b/elenasrc3/common/streams.h
index 815fb6adc6..2bf5a1b1d9 100644
--- a/elenasrc3/common/streams.h
+++ b/elenasrc3/common/streams.h
@@ -3,7 +3,7 @@
//
// This header contains the declaration of abstract stream reader
// and writer classes
-// (C)2021-2023, by Aleksey Rakov
+// (C)2021-2024, by Aleksey Rakov
//---------------------------------------------------------------------------
#ifndef STREAMS_H
@@ -37,6 +37,13 @@ namespace elena_lang
return value;
}
+ static unsigned long long getQWord(MemoryBase* source, pos_t position)
+ {
+ unsigned long long value = 0;
+ source->read(position, &value, sizeof(value));
+
+ return value;
+ }
static void maskDWord(MemoryBase* source, pos_t position, ref_t mask)
{
diff --git a/elenasrc3/elc/cliconst.h b/elenasrc3/elc/cliconst.h
index 70105d76ca..76b30ef11c 100644
--- a/elenasrc3/elc/cliconst.h
+++ b/elenasrc3/elc/cliconst.h
@@ -13,7 +13,7 @@
namespace elena_lang
{
- #define ELC_REVISION_NUMBER 0x026F
+ #define ELC_REVISION_NUMBER 0x0008
#if defined _M_IX86 || _M_X64
diff --git a/elenasrc3/elc/compiler.cpp b/elenasrc3/elc/compiler.cpp
index c5bfe3cd2b..88a5c12f8c 100644
--- a/elenasrc3/elc/compiler.cpp
+++ b/elenasrc3/elc/compiler.cpp
@@ -167,6 +167,56 @@ inline bool isConstant(ObjectKind kind)
}
}
+inline bool isSingleObject(ObjectKind kind)
+{
+ switch (kind)
+ {
+ case ObjectKind::CharacterLiteral:
+ case ObjectKind::ConstantLiteral:
+ case ObjectKind::MssgNameLiteral:
+ case ObjectKind::MssgLiteral:
+ case ObjectKind::ExtMssgLiteral:
+ case ObjectKind::Nil:
+ case ObjectKind::Class:
+ case ObjectKind::ClassSelf:
+ case ObjectKind::ConstructorSelf:
+ case ObjectKind::Param:
+ case ObjectKind::ParamReference:
+ case ObjectKind::ParamAddress:
+ case ObjectKind::ByRefParam:
+ case ObjectKind::ByRefParamAddress:
+ case ObjectKind::Local:
+ case ObjectKind::LocalReference:
+ case ObjectKind::RefLocal:
+ case ObjectKind::TempLocal:
+ case ObjectKind::SelfLocal:
+ case ObjectKind::SuperLocal:
+ case ObjectKind::ReadOnlySelfLocal:
+ case ObjectKind::LocalAddress:
+ case ObjectKind::TempLocalAddress:
+ case ObjectKind::ReadOnlyFieldAddress:
+ case ObjectKind::FieldAddress:
+ case ObjectKind::ReadOnlyField:
+ case ObjectKind::Field:
+ case ObjectKind::Outer:
+ case ObjectKind::OuterField:
+ case ObjectKind::OuterSelf:
+ case ObjectKind::Closure:
+ case ObjectKind::ClassConstant:
+ case ObjectKind::Constant:
+ case ObjectKind::ConstArray:
+ case ObjectKind::StaticField:
+ case ObjectKind::StaticConstField:
+ case ObjectKind::ClassStaticConstField:
+ case ObjectKind::LocalField:
+ return true;
+ default:
+ return isConstant(kind);
+ }
+
+ return false;
+}
+
inline bool areConstants(ArgumentsInfo& args)
{
for (size_t i = 0; i < args.count(); i++) {
@@ -2935,6 +2985,11 @@ inline bool checkPreviousDeclaration(SyntaxNode node, ustr_t name)
return false;
}
+inline bool isInterface(int flagMask)
+{
+ return flagMask == elInterface || flagMask == elWeakInterface;
+}
+
bool Compiler :: generateClassField(ClassScope& scope, FieldAttributes& attrs, ustr_t name, int sizeHint,
TypeInfo typeInfo, bool singleField)
{
@@ -2943,8 +2998,8 @@ bool Compiler :: generateClassField(ClassScope& scope, FieldAttributes& attrs, u
bool readOnly = attrs.isReadonly;
ref_t flags = scope.info.header.flags;
- // a role cannot have fields
- if (test(flags, elStateless))
+ // a role / interface cannot have fields
+ if (test(flags, elStateless) || isInterface(flags & elDebugMask))
return false;
SizeInfo sizeInfo = {};
@@ -4216,7 +4271,6 @@ ref_t Compiler :: resolvePrimitiveType(ModuleScopeBase& moduleScope, ustr_t ns,
}
}
-
void Compiler :: declareClassAttributes(ClassScope& scope, SyntaxNode node, ref_t& flags)
{
SyntaxNode current = node.firstChild();
@@ -4240,6 +4294,10 @@ void Compiler :: declareClassAttributes(ClassScope& scope, SyntaxNode node, ref_
// handle the abstract flag
if (test(scope.info.header.flags, elAbstract)) {
+ // clear the interface flag by inheriting
+ if (isInterface(scope.info.header.flags & elDebugMask))
+ scope.info.header.flags &= ~elDebugMask;
+
if (!test(flags, elAbstract)) {
scope.abstractBasedMode = true;
scope.info.header.flags &= ~elAbstract;
@@ -5136,6 +5194,9 @@ TypeInfo Compiler :: resolveTypeScope(Scope& scope, SyntaxNode node, TypeAttribu
case SyntaxKey::Type:
elementRef = resolveStrongTypeAttribute(scope, current, declarationMode, false);
break;
+ case SyntaxKey::TemplateType:
+ elementRef = resolveTypeAttribute(scope, current, attributes, declarationMode, allowRole).typeRef;
+ break;
case SyntaxKey::identifier:
case SyntaxKey::reference:
elementRef = resolveTypeIdentifier(scope, current.identifier(), node.key, declarationMode, allowRole);
@@ -6670,6 +6731,9 @@ ObjectInfo Compiler :: mapTerminal(Scope& scope, SyntaxNode node, TypeInfo decla
break;
}
}
+ else if (node == SyntaxKey::Type && variableMode) {
+ return { ObjectKind::Class, {}, declaredTypeInfo.typeRef };
+ }
else retVal = defineTerminalInfo(scope, node, declaredTypeInfo, variableMode, forwardMode,
refOp, mssgOp, memberMode, invalid, attrs);
@@ -6726,7 +6790,6 @@ ObjectInfo Compiler :: mapObject(Scope& scope, SyntaxNode node, EAttrs mode)
}
return {};
}
-
if (terminalNode.nextNode() == SyntaxKey::TemplateArg && !EAttrs::test(mode.attrs, ExpressionAttribute::NewOp)) {
scope.raiseError(errInvalidSyntax, node);
}
@@ -7344,7 +7407,7 @@ void Compiler :: compileMethodCode(BuildTreeWriter& writer, ClassScope* classSco
}
break;
case SyntaxKey::Redirect:
- retVal = compileRedirect(writer, codeScope, bodyNode);
+ retVal = compileRedirect(writer, codeScope, bodyNode, scope.info.outputRef);
break;
default:
break;
@@ -7538,7 +7601,7 @@ void Compiler :: compileMultidispatch(BuildTreeWriter& writer, CodeScope& scope,
}
}
-ObjectInfo Compiler :: compileRedirect(BuildTreeWriter& writer, CodeScope& codeScope, SyntaxNode node)
+ObjectInfo Compiler :: compileRedirect(BuildTreeWriter& writer, CodeScope& codeScope, SyntaxNode node, ref_t outputRef)
{
Expression expression(this, codeScope, writer);
ArgumentsInfo arguments;
@@ -7563,7 +7626,11 @@ ObjectInfo Compiler :: compileRedirect(BuildTreeWriter& writer, CodeScope& codeS
_logic->setSignatureStacksafe(*codeScope.moduleScope, signRef, resolution.stackSafeAttr);
ObjectInfo retVal = expression.compileMessageOperation({}, target, resolution,
- signRef, arguments, EAttr::None, & updatedOuterArgs);
+ signRef, arguments, EAttr::None, &updatedOuterArgs);
+
+ if (outputRef) {
+ expression.convertObject(node, expression.saveToTempLocal(retVal), outputRef, true, false);
+ }
expression.scope.syncStack();
@@ -8412,6 +8479,31 @@ void Compiler :: initializeMethod(ClassScope& scope, MethodScope& methodScope, S
}
}
+void Compiler :: compileProxyDispatcher(BuildTreeWriter& writer, CodeScope& codeScope, SyntaxNode node)
+{
+ SyntaxNode objNode = node.firstChild(SyntaxKey::DeclarationMask).firstChild();
+
+ // NOTE : the redirect target must be a simple variable
+ assert(objNode == SyntaxKey::Object);
+
+ Expression expression(this, codeScope, writer);
+
+ ObjectInfo target = expression.compile(objNode, 0, EAttr::None, nullptr);
+ switch (target.kind) {
+ // NOTE : the redirect operation must be done without creating a new frame
+ case ObjectKind::OuterSelf:
+ case ObjectKind::Outer:
+ writer.appendNode(BuildKey::Argument);
+ writer.appendNode(BuildKey::Field, target.reference);
+ break;
+ default:
+ codeScope.raiseError(errInvalidOperation, node);
+ break;
+ }
+
+ writer.appendNode(BuildKey::RedirectOp);
+}
+
void Compiler :: compileRedirectDispatcher(BuildTreeWriter& writer, MethodScope& scope, CodeScope& codeScope, SyntaxNode node,
bool withGenerics)
{
@@ -8487,6 +8579,8 @@ inline bool hasVariadicFunctionDispatcher(Compiler::ClassScope* classScope, bool
void Compiler :: compileDispatcherMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node,
bool withGenerics, bool withOpenArgGenerics)
{
+ ClassScope* classScope = Scope::getScope(scope, Scope::ScopeLevel::Class);
+
CodeScope codeScope(&scope);
beginMethod(writer, scope, node, BuildKey::Method, false);
@@ -8499,7 +8593,10 @@ void Compiler :: compileDispatcherMethod(BuildTreeWriter& writer, MethodScope& s
writer.appendNode(BuildKey::Import, current.arg.reference);
break;
case SyntaxKey::Redirect:
- compileRedirectDispatcher(writer, scope, codeScope, current, withGenerics);
+ if (node.existChild(SyntaxKey::ProxyDispatcher)) {
+ compileProxyDispatcher(writer, codeScope, current);
+ }
+ else compileRedirectDispatcher(writer, scope, codeScope, current, withGenerics);
break;
default:
scope.raiseError(errInvalidOperation, node);
@@ -8509,8 +8606,6 @@ void Compiler :: compileDispatcherMethod(BuildTreeWriter& writer, MethodScope& s
else {
// if it is an implicit dispatcher
if (withGenerics) {
- ClassScope* classScope = Scope::getScope(scope, Scope::ScopeLevel::Class);
-
// !! temporally
if (withOpenArgGenerics)
scope.raiseError(errInvalidOperation, node);
@@ -8529,8 +8624,6 @@ void Compiler :: compileDispatcherMethod(BuildTreeWriter& writer, MethodScope& s
else if (withOpenArgGenerics) {
Expression expression(this, codeScope, writer);
- ClassScope* classScope = Scope::getScope(scope, Scope::ScopeLevel::Class);
-
ref_t mask = VARIADIC_MESSAGE;
bool mixedDispatcher = false;
bool variadicFunction = hasVariadicFunctionDispatcher(classScope, mixedDispatcher);
@@ -8923,6 +9016,31 @@ void Compiler :: injectInterfaceDispatch(Scope& scope, SyntaxNode node, ref_t pa
}
}
+bool Compiler :: isProxy(Scope& scope, SyntaxNode node)
+{
+ SyntaxNode current = node.firstChild();
+ while (current != SyntaxKey::None) {
+ switch (current.key) {
+ case SyntaxKey::Method:
+ if (current.arg.reference == scope.moduleScope->buildins.dispatch_message) {
+ SyntaxNode exprNode = current.findChild(SyntaxKey::Redirect).firstChild();
+ if (exprNode.firstChild() != SyntaxKey::Object || exprNode.firstChild().nextNode() != SyntaxKey::None) {
+ return false;
+ }
+ else current.appendChild(SyntaxKey::ProxyDispatcher);
+ }
+ else return false;
+ break;
+ default:
+ return false;
+ }
+
+ current = current.nextNode();
+ }
+
+ return true;
+}
+
void Compiler :: compileNestedClass(BuildTreeWriter& writer, ClassScope& scope, SyntaxNode node, ref_t parentRef)
{
NamespaceScope* ns = Scope::getScope(scope, Scope::ScopeLevel::Namespace);
@@ -8967,6 +9085,9 @@ void Compiler :: compileNestedClass(BuildTreeWriter& writer, ClassScope& scope,
generateClassDeclaration(scope, node, elNestedClass | elSealed);
+ // check if the nested class is a proxy class, and inject the required attribute
+ bool proxy = scope.info.header.parentRef == scope.moduleScope->buildins.superReference && isProxy(scope, node);
+
scope.save();
BuildNode buildNode = writer.CurrentNode();
@@ -8985,6 +9106,11 @@ void Compiler :: compileNestedClass(BuildTreeWriter& writer, ClassScope& scope,
// NOTE : it should be called after the code compilation to take into consideration outer fields
_logic->tweakClassFlags(*scope.moduleScope, scope.reference, scope.info, scope.isClassClass());
+ // validate the proxy class and set the flag
+ if (proxy && !_logic->validateDispatcherType(scope.info)) {
+ scope.raiseError(errInvalidOperation, node);
+ }
+
// NOTE : compile once again only auto generated methods
compileVMT(nestedWriter, scope, node, true, false);
@@ -10241,7 +10367,7 @@ bool Compiler::Class :: isParentDeclared(SyntaxNode node)
void Compiler::Class :: declare(SyntaxNode node)
{
bool extensionDeclaration = isExtensionDeclaration(node);
- resolveClassPostfixes(node, extensionDeclaration/*, lxParent*/);
+ resolveClassPostfixes(node, extensionDeclaration);
ref_t declaredFlags = 0;
compiler->declareClassAttributes(scope, node, declaredFlags);
@@ -10540,9 +10666,12 @@ ObjectInfo Compiler::Expression :: compileReturning(SyntaxNode node, EAttr mode,
bool dynamicRequired = EAttrs::testAndExclude(mode, EAttr::DynamicObject);
CodeScope* codeScope = Scope::getScope(scope, Scope::ScopeLevel::Code);
- if (codeScope == nullptr)
+ if (codeScope == nullptr) {
scope.raiseError(errInvalidOperation, node);
+ return {};
+ }
+
if (compiler->_withDebugInfo) {
writer->appendNode(BuildKey::OpenStatement);
addBreakpoint(*writer, findObjectNode(node), BuildKey::Breakpoint);
@@ -13134,7 +13263,11 @@ ObjectInfo Compiler::Expression :: compileBranchingOperation(SyntaxNode node, Ob
writer->newNode(op, operatorId);
writer->appendNode(BuildKey::Const, scope.moduleScope->branchingInfo.trueRef);
- retVal = compileBranchingOperands(rnode, r2node, retValExpected, withoutDebugInfo);
+ if (retValExpected && argLen == 3 && (roperand.kind == ObjectKind::Object) && (roperand2.kind == ObjectKind::Object)) {
+ BuildNode opNode = writer->CurrentNode();
+ retVal = compileTernaryOperands(rnode, r2node, opNode, withoutDebugInfo);
+ }
+ else retVal = compileBranchingOperands(rnode, r2node, retValExpected, withoutDebugInfo);
}
else {
mssg_t message = 0;
@@ -13177,8 +13310,8 @@ ObjectInfo Compiler::Expression :: compileBranchingOperands(SyntaxNode rnode, Sy
ObjectInfo subRetCode = {};
bool oldWithRet = codeScope->withRetStatement;
+ EAttr mode = retValExpected ? EAttr::RetValExpected : EAttr::None;
if (rnode == SyntaxKey::ClosureBlock || rnode == SyntaxKey::SwitchCode) {
- EAttr mode = retValExpected ? EAttr::RetValExpected : EAttr::None;
if (withoutDebugInfo)
mode = mode | EAttr::NoDebugInfo;
@@ -13186,7 +13319,7 @@ ObjectInfo Compiler::Expression :: compileBranchingOperands(SyntaxNode rnode, Sy
subRetCode = compileSubCode(rnode.firstChild(), mode);
}
- else subRetCode = compile(rnode, 0, EAttr::None, nullptr);
+ else subRetCode = compile(rnode, 0, mode, nullptr);
if (retValExpected) {
writeObjectInfo(subRetCode);
@@ -13202,7 +13335,6 @@ ObjectInfo Compiler::Expression :: compileBranchingOperands(SyntaxNode rnode, Sy
bool withRet = codeScope->withRetStatement;
codeScope->withRetStatement = false;
- EAttr mode = retValExpected ? EAttr::RetValExpected : EAttr::None;
if (withoutDebugInfo)
mode = mode | EAttr::NoDebugInfo;
@@ -13212,7 +13344,7 @@ ObjectInfo Compiler::Expression :: compileBranchingOperands(SyntaxNode rnode, Sy
codeScope->withRetStatement = oldWithRet;
}
}
- else elseSubRetCode = compile(r2node, 0, EAttr::None, nullptr);
+ else elseSubRetCode = compile(r2node, 0, mode, nullptr);
if (retValExpected) {
writeObjectInfo(elseSubRetCode, r2node);
@@ -13234,6 +13366,41 @@ ObjectInfo Compiler::Expression :: compileBranchingOperands(SyntaxNode rnode, Sy
return retVal;
}
+ObjectInfo Compiler::Expression :: compileTernaryOperands(SyntaxNode rnode, SyntaxNode r2node, BuildNode& opNode, bool withoutDebugInfo)
+{
+ CodeScope* codeScope = Scope::getScope(scope, Scope::ScopeLevel::Code);
+
+ writer->newNode(BuildKey::Tape);
+
+ bool oldWithRet = codeScope->withRetStatement;
+ ObjectInfo lexpr = compile(rnode, 0, EAttr::RetValExpected, nullptr);
+
+ writeObjectInfo(lexpr);
+
+ writer->closeNode();
+
+ TypeInfo retType = {};
+
+ // NOTE : it should immediately follow if-block
+ writer->newNode(BuildKey::Tape);
+ ObjectInfo rexpr = compile(r2node, 0, EAttr::RetValExpected, nullptr);
+
+ writeObjectInfo(rexpr, r2node);
+
+ if (lexpr.typeInfo == rexpr.typeInfo)
+ retType = rexpr.typeInfo;
+
+ writer->closeNode();
+
+ if (isSingleObject(lexpr.kind) && isSingleObject(rexpr.kind)) {
+ opNode.setKey(BuildKey::TernaryOp);
+ }
+
+ writer->closeNode();
+
+ return { ObjectKind::Object, retType, 0 };
+}
+
ObjectInfo Compiler::Expression :: compileMessageOperationR(ObjectInfo target, SyntaxNode messageNode, bool propertyMode)
{
ArgumentsInfo arguments;
diff --git a/elenasrc3/elc/compiler.h b/elenasrc3/elc/compiler.h
index 7817a77b2e..40db9b5e81 100644
--- a/elenasrc3/elc/compiler.h
+++ b/elenasrc3/elc/compiler.h
@@ -1258,6 +1258,7 @@ namespace elena_lang
ObjectInfo saveToTempLocal(ObjectInfo object);
ObjectInfo compileBranchingOperands(SyntaxNode rnode, SyntaxNode r2node, bool retValExpected, bool withoutDebugInfo);
+ ObjectInfo compileTernaryOperands(SyntaxNode rnode, SyntaxNode r2node, BuildNode& opNode, bool withoutDebugInfo);
ObjectInfo compileNativeConversion(SyntaxNode node, ObjectInfo source, ref_t operationKey);
@@ -1410,6 +1411,8 @@ namespace elena_lang
static bool isClassClassOperation(Scope& scope, ObjectInfo target);
+ static bool isProxy(Scope& scope, SyntaxNode node);
+
ref_t declareMultiType(Scope& scope, SyntaxNode& node, ref_t elementRef);
void declareClassAttributes(ClassScope& scope, SyntaxNode node, ref_t& fldeclaredFlagsags);
@@ -1576,9 +1579,10 @@ namespace elena_lang
void compileRedirectDispatcher(BuildTreeWriter& writer, MethodScope& scope, CodeScope& codeScope, SyntaxNode node,
bool withGenerics);
+ void compileProxyDispatcher(BuildTreeWriter& writer, CodeScope& codeScope, SyntaxNode node);
ObjectInfo compileResendCode(BuildTreeWriter& writer, CodeScope& codeScope, ObjectInfo source, SyntaxNode node);
- ObjectInfo compileRedirect(BuildTreeWriter& writer, CodeScope& codeScope, SyntaxNode node);
+ ObjectInfo compileRedirect(BuildTreeWriter& writer, CodeScope& codeScope, SyntaxNode node, ref_t outputRef);
ObjectInfo compileCode(BuildTreeWriter& writer, CodeScope& codeScope, SyntaxNode node, bool closureMode, bool noDebugInfoMode = false);
void beginMethod(BuildTreeWriter& writer, MethodScope& scope, SyntaxNode node, BuildKey scopeKey,
diff --git a/elenasrc3/elc/compilerlogic.cpp b/elenasrc3/elc/compilerlogic.cpp
index 2bc3f7071a..3b181f50fa 100644
--- a/elenasrc3/elc/compilerlogic.cpp
+++ b/elenasrc3/elc/compilerlogic.cpp
@@ -809,8 +809,12 @@ bool CompilerLogic :: validateClassAttribute(ref_t attribute, ref_t& flags, Visi
case V_SINGLETON:
flags |= elRole | elSealed | elStateless;
break;
- case V_LIMITED:
- flags |= (elClosed | elAbstract | elNoCustomDispatcher);
+ case V_INTERFACE:
+ if (!(flags & elDebugMask)) {
+ flags |= (elClosed | elAbstract | elNoCustomDispatcher);
+ flags |= elInterface;
+ }
+ else return false;
break;
case V_ABSTRACT:
flags |= elAbstract;
@@ -1474,6 +1478,22 @@ void CompilerLogic :: tweakClassFlags(ModuleScopeBase& scope, ref_t classRef, Cl
break;
}
}
+ else if ((info.header.flags & elDebugMask) == elInterface) {
+ // verify if it is a weak interface (an interface without output type specified)
+ bool isWeakInterface = true;
+ for (auto it = info.methods.start(); !it.eof(); ++it) {
+ auto methodInfo = *it;
+
+ if (!methodInfo.inherited && methodInfo.outputRef && methodInfo.outputRef != classRef) {
+ isWeakInterface = false;
+ break;
+ }
+ }
+ if (isWeakInterface) {
+ info.header.flags &= ~elDebugMask;
+ info.header.flags |= elWeakInterface;
+ }
+ }
}
void CompilerLogic :: tweakPrimitiveClassFlags(ClassInfo& info, ref_t classRef)
@@ -2946,4 +2966,18 @@ pos_t CompilerLogic :: definePadding(ModuleScopeBase& scope, pos_t offset, pos_t
default:
return align(offset, scope.ptrSize) - offset;
}
-}
\ No newline at end of file
+}
+
+bool CompilerLogic :: validateDispatcherType(ClassInfo& classInfo)
+{
+ bool isProxy = classInfo.fields.count() == 1 && test(classInfo.header.flags, elWithCustomDispatcher | elNestedClass | elSealed)
+ && !testany(classInfo.header.flags, elWithGenerics | elWithVariadics | elWithYieldable | elStructure);
+
+ if (isProxy && (classInfo.header.flags & elDebugMask) == 0) {
+ classInfo.header.flags |= elProxy;
+
+ return true;
+ }
+
+ return false;
+}
diff --git a/elenasrc3/elc/compilerlogic.h b/elenasrc3/elc/compilerlogic.h
index 860c3ef3a3..a6344a5156 100644
--- a/elenasrc3/elc/compilerlogic.h
+++ b/elenasrc3/elc/compilerlogic.h
@@ -203,6 +203,8 @@ namespace elena_lang
bool isNeedVerification(ClassInfo& info, VirtualMethodList& implicitMultimethods);
bool verifyMultimethod(ModuleScopeBase& scope, ClassInfo& info, mssg_t message);
+ bool validateDispatcherType(ClassInfo& classInfo);
+
mssg_t resolveMultimethod(ModuleScopeBase& scope, mssg_t weakMessage, ref_t targetRef,
ref_t implicitSignatureRef, int& stackSafeAttr, bool selfCall);
diff --git a/elenasrc3/elc/derivation.cpp b/elenasrc3/elc/derivation.cpp
index 4c3459028d..3c66371ab3 100644
--- a/elenasrc3/elc/derivation.cpp
+++ b/elenasrc3/elc/derivation.cpp
@@ -365,14 +365,28 @@ void SyntaxTreeBuilder :: flushTemplateType(SyntaxTreeWriter& writer, Scope& sco
}
}
-void SyntaxTreeBuilder :: flushArrayType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, int nestLevel)
+void SyntaxTreeBuilder :: flushArrayType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, bool exprMode, int nestLevel)
{
SyntaxNode current = node.firstChild();
ref_t attributeCategory = V_CATEGORY_MAX;
while (current != SyntaxKey::None) {
if (current == SyntaxKey::ArrayType) {
- flushArrayType(writer, scope, current, nestLevel + 1);
+ flushArrayType(writer, scope, current, exprMode, nestLevel + 1);
+ }
+ else if (current == SyntaxKey::TemplateType) {
+ for (int i = 0; i < nestLevel; i++)
+ writer.newNode(SyntaxKey::ArrayType);
+
+ if (exprMode) {
+ writer.newNode(SyntaxKey::TemplateType);
+ flushTemplateType(writer, scope, current);
+ writer.closeNode();
+ }
+ else flushTemplateType(writer, scope, current, false);
+
+ for (int i = 0; i < nestLevel; i++)
+ writer.closeNode();
}
else {
bool allowType = current.nextNode() == SyntaxKey::None;
@@ -451,11 +465,11 @@ void SyntaxTreeBuilder :: flushObject(SyntaxTreeWriter& writer, Scope& scope, Sy
if (current.nextNode() == SyntaxKey::identifier) {
SyntaxNode identNode = node.lastChild(SyntaxKey::TerminalMask);
- flushArrayType(writer, scope, current);
+ flushArrayType(writer, scope, current, true);
flushNode(writer, scope, identNode);
}
- else flushArrayType(writer, scope, current);
+ else flushArrayType(writer, scope, current, true);
}
else if (current == SyntaxKey::Expression) {
//HOTFIX : expression cannot be inside an object
@@ -746,7 +760,7 @@ void SyntaxTreeBuilder :: flushDescriptor(SyntaxTreeWriter& writer, Scope& scope
bool allowType = nameNode.key == SyntaxKey::None || nextNode == nameNode;
if (current == SyntaxKey::ArrayType) {
//flushAttribute(writer, scope, current, attributeCategory, allowType, true);
- flushArrayType(writer, scope, current);
+ flushArrayType(writer, scope, current, false);
}
else if (current == SyntaxKey::TemplateType) {
flushTemplateType(writer, scope, current, false);
@@ -774,8 +788,6 @@ void SyntaxTreeBuilder :: flushDescriptor(SyntaxTreeWriter& writer, Scope& scope
writer.newNode(key, attrRef);
flushNode(writer, scope, current);
writer.closeNode();
-
-
}
else flushNode(writer, scope, current);
}
@@ -1608,7 +1620,7 @@ SyntaxTreeBuilder::ScopeType SyntaxTreeBuilder :: defineTemplateType(SyntaxNode
void SyntaxTreeBuilder :: flushDeclaration(SyntaxTreeWriter& writer, SyntaxNode node)
{
- Scope scope;
+ Scope scope(_noDebugInfo);
writer.newNode(node.key);
diff --git a/elenasrc3/elc/derivation.h b/elenasrc3/elc/derivation.h
index 318bea59c6..c07811c7d1 100644
--- a/elenasrc3/elc/derivation.h
+++ b/elenasrc3/elc/derivation.h
@@ -99,11 +99,15 @@ namespace elena_lang
}
Scope()
+ : Scope(false)
+ {
+ }
+ Scope(bool ignoreTerminalInfo)
: arguments(0), parameters(0)
{
- type = ScopeType::Unknown;
- ignoreTerminalInfo = false;
- nestedLevel = 0;
+ this->type = ScopeType::Unknown;
+ this->ignoreTerminalInfo = ignoreTerminalInfo;
+ this->nestedLevel = 0;
}
};
@@ -117,6 +121,8 @@ namespace elena_lang
ModuleScopeBase* _moduleScope;
TemplateProssesorBase* _templateProcessor;
+ bool _noDebugInfo;
+
ScopeType defineTemplateType(SyntaxNode node);
ref_t mapAttribute(SyntaxNode node, bool allowType, ref_t& previusCategory);
@@ -141,7 +147,7 @@ namespace elena_lang
void flushTemplateArg(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, bool allowType);
void flushTemplageExpression(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, SyntaxKey type, bool allowType);
void flushTemplateType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, bool exprMode = true);
- void flushArrayType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, int nestLevel = 1);
+ void flushArrayType(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node, bool exprMode, int nestLevel = 1);
void flushMessage(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node);
void flushResend(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node);
void flushObject(SyntaxTreeWriter& writer, Scope& scope, SyntaxNode node);
@@ -220,6 +226,17 @@ namespace elena_lang
_writer.clear();
_writer.newNode(SyntaxKey::Root);
+ clear();
+ }
+ SyntaxTreeBuilder(SyntaxNode rootNode, ErrorProcessor* errorProcessor,
+ ModuleScopeBase* moduleScope, TemplateProssesorBase* templateProcessor, bool noDebugInfo)
+ : _writer(rootNode), _cacheWriter(_cache)
+ {
+ _errorProcessor = errorProcessor;
+ _moduleScope = moduleScope;
+ _templateProcessor = templateProcessor;
+ _noDebugInfo = noDebugInfo;
+
clear();
}
};
diff --git a/elenasrc3/elena-tests/bt_optimization.cpp b/elenasrc3/elena-tests/bt_optimization.cpp
index 1f3dbf645b..e557ceae13 100644
--- a/elenasrc3/elena-tests/bt_optimization.cpp
+++ b/elenasrc3/elena-tests/bt_optimization.cpp
@@ -9,22 +9,10 @@
#include "serializer.h"
#include "bcwriter.h"
-#include
-
using namespace elena_lang;
constexpr auto BT_RULES_FILE = "bt_rules60.dat";
-inline void getAppPath(PathString& appPath)
-{
- wchar_t path[MAX_PATH + 1];
-
- ::GetModuleFileName(nullptr, path, MAX_PATH);
-
- appPath.copySubPath(path, false);
- appPath.lower();
-}
-
// --- BTOptimization1 ---
constexpr auto Declaration1_1 = "namespace (class ( nameattr (identifier \"Object\" ())) class (attribute -2147467263 () attribute -2147475455 () attribute -2147479550 () nameattr (identifier \"Struct\" ()) field (attribute -2147475454 () attribute -2147481597 () nameattr (identifier \"_value\" ())dimension (integer \"4\" ()))) class ( attribute -2147471359 () nameattr (identifier \"TestReference\" ()) field (attribute -2147475454 () type (identifier \"Struct\" ()) nameattr (identifier \"_value\" ())) ) class (attribute -2147467263 ()attribute -2147479546 () nameattr (identifier \"Tester\" ()) method (type (identifier \"Struct\" ()) nameattr (identifier \"getValue\" ())code ())))";
@@ -384,83 +372,6 @@ void PrimitiveStructAlignment:: SetUp()
expectedSize = 2;
}
-// --- Scenario1Test ---
-
-void Scenario1Test:: LoadDeclarationScenario(ustr_t common, ustr_t descr1, ustr_t descr2)
-{
- IdentifierString descr(descr1, " ", descr2);
-
- DynamicUStr syntax(common);
-
- size_t index = common.findStr("$1");
- if (index != NOTFOUND_POS) {
- syntax.cut(index, 2);
- syntax.insert(*descr, index);
- }
-
- SyntaxTreeSerializer::load(syntax.str(), declarationNode);
-}
-
-void Scenario1Test :: LoadDeclarationScenario(ustr_t common, ustr_t descr1, ustr_t descr2, ustr_t descr3)
-{
- DynamicUStr syntax(common);
-
- size_t index = common.findStr("$1");
- if (index != NOTFOUND_POS) {
- syntax.cut(index, 2);
-
- syntax.insert(descr3, index);
- syntax.insert(" ", index);
- syntax.insert(descr2, index);
- syntax.insert(" ", index);
- syntax.insert(descr1, index);
- }
-
- SyntaxTreeSerializer::load(syntax.str(), declarationNode);
-}
-
-void Scenario1Test :: LoadDeclarationScenario(ustr_t common, ustr_t descr1, ustr_t descr2, ustr_t descr3, ustr_t descr4)
-{
- DynamicUStr syntax(common);
-
- size_t index = common.findStr("$1");
- if (index != NOTFOUND_POS) {
- syntax.cut(index, 2);
-
- syntax.insert(descr4, index);
- syntax.insert(" ", index);
- syntax.insert(descr3, index);
- syntax.insert(" ", index);
- syntax.insert(descr2, index);
- syntax.insert(" ", index);
- syntax.insert(descr1, index);
- }
-
- SyntaxTreeSerializer::load(syntax.str(), declarationNode);
-}
-
-void Scenario1Test :: LoadDeclarationScenario(ustr_t common, ustr_t descr1, ustr_t descr2, ustr_t descr3, ustr_t descr4, ustr_t descr5)
-{
- DynamicUStr syntax(common);
-
- size_t index = common.findStr("$1");
- if (index != NOTFOUND_POS) {
- syntax.cut(index, 2);
-
- syntax.insert(descr5, index);
- syntax.insert(" ", index);
- syntax.insert(descr4, index);
- syntax.insert(" ", index);
- syntax.insert(descr3, index);
- syntax.insert(" ", index);
- syntax.insert(descr2, index);
- syntax.insert(" ", index);
- syntax.insert(descr1, index);
- }
-
- SyntaxTreeSerializer::load(syntax.str(), declarationNode);
-}
-
// --- DispatchTest ---
void DispatchTest :: SetUp()
diff --git a/elenasrc3/elena-tests/bt_optimization.h b/elenasrc3/elena-tests/bt_optimization.h
index b4e52db6ce..aa68e87373 100644
--- a/elenasrc3/elena-tests/bt_optimization.h
+++ b/elenasrc3/elena-tests/bt_optimization.h
@@ -8,7 +8,6 @@
#ifndef BTOPTIMIZATION_H
#define BTOPTIMIZATION_H
-#include "pch.h"
#include "tests_common.h"
namespace elena_lang
@@ -63,22 +62,12 @@ namespace elena_lang
}
};
- class Scenario1Test : public testing::Test
+ class Scenario1Test : public BaseFixture
{
protected:
- SyntaxTree syntaxTree;
BuildTree buildTree;
- SyntaxNode declarationNode;
-
BuildNode controlOutputNode;
-
- CompilerEnvironment env;
-
- void LoadDeclarationScenario(ustr_t common, ustr_t descr1, ustr_t descr2);
- void LoadDeclarationScenario(ustr_t common, ustr_t descr1, ustr_t descr2, ustr_t descr3);
- void LoadDeclarationScenario(ustr_t common, ustr_t descr1, ustr_t descr2, ustr_t descr3, ustr_t descr4);
- void LoadDeclarationScenario(ustr_t common, ustr_t descr1, ustr_t descr2, ustr_t descr3, ustr_t descr4, ustr_t descr5);
};
class DispatchTest : public Scenario1Test
diff --git a/elenasrc3/elena-tests/declaration.cpp b/elenasrc3/elena-tests/declaration.cpp
new file mode 100644
index 0000000000..a5e9a0f1cd
--- /dev/null
+++ b/elenasrc3/elena-tests/declaration.cpp
@@ -0,0 +1,95 @@
+//---------------------------------------------------------------------------
+// E L E N A P r o j e c t: ELENA Compiler
+//
+// This header contains ELENA Test Optimization Fixture implementation
+// (C)2024, by Aleksey Rakov
+//---------------------------------------------------------------------------
+
+#include "declaration.h"
+#include "serializer.h"
+#include "bcwriter.h"
+
+#include "parser.h"
+#include "cliconst.h"
+#include "derivation.h"
+
+using namespace elena_lang;
+
+constexpr auto Field_TemplateBasedArray = "namespace (class (nameattr (identifier \"A\" ())field (array_type (template_type (identifier \"VarTuple\" () template_arg (type(identifier \"object\" ())) template_arg (type(identifier \"object\" ()))))nameattr (identifier \"_array\" ())))";
+constexpr auto New_TemplateBasedArray = "namespace (class (attribute -2147467263 (identifier \"public\" ())nameattr (identifier \"program\" ())attribute -2147479546 ()method (attribute -2147479540 ()code (expression (assign_operation (object (attribute -2147479539 (identifier \"var\" ())identifier \"array\" ())expression (message_operation (object (array_type (template_type (attribute -2147479534 (identifier \"new\" ())identifier \"VarTuple\" ()template_arg (type (identifier \"object\" ()))template_arg (type (identifier \"object\" ())))))expression (object (integer \"10\" ()))))))EOP (eop \"}\" ())))))";
+
+constexpr auto Src_Field_TemplateBasedArray = "A { VarTuple | |