Возможность импортировать несколько модулей use ["std", "types", "files"]

This commit is contained in:
Victor 2018-12-12 21:26:15 +02:00
parent 52d7121751
commit 8965174589
9 changed files with 70 additions and 29 deletions

View File

@ -1,5 +1,9 @@
package com.annimon.ownlang.parser.ast; package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.exceptions.TypeException;
import com.annimon.ownlang.lib.ArrayValue;
import com.annimon.ownlang.lib.Types;
import com.annimon.ownlang.lib.Value;
import com.annimon.ownlang.modules.Module; import com.annimon.ownlang.modules.Module;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -21,9 +25,24 @@ public final class UseStatement extends InterruptableNode implements Statement {
@Override @Override
public void execute() { public void execute() {
super.interruptionCheck(); super.interruptionCheck();
final Value value = expression.eval();
switch (value.type()) {
case Types.ARRAY:
for (Value module : ((ArrayValue) value)) {
loadModule(module.asString());
}
break;
case Types.STRING:
loadModule(value.asString());
break;
default:
throw new TypeException("Array or string required");
}
}
private void loadModule(String name) {
try { try {
final String moduleName = expression.eval().asString(); final Module module = (Module) Class.forName(String.format(PACKAGE, name, name)).newInstance();
final Module module = (Module) Class.forName(String.format(PACKAGE, moduleName, moduleName)).newInstance();
module.init(); module.init();
} catch (Exception ex) { } catch (Exception ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);
@ -31,14 +50,30 @@ public final class UseStatement extends InterruptableNode implements Statement {
} }
public void loadConstants() { public void loadConstants() {
final Value value = expression.eval();
switch (value.type()) {
case Types.ARRAY:
for (Value module : ((ArrayValue) value)) {
loadConstants(module.asString());
}
break;
case Types.STRING:
loadConstants(value.asString());
break;
default:
throw new TypeException("Array or string required");
}
}
private void loadConstants(String moduleName) {
try { try {
final String moduleName = expression.eval().asString();
final Class<?> moduleClass = Class.forName(String.format(PACKAGE, moduleName, moduleName)); final Class<?> moduleClass = Class.forName(String.format(PACKAGE, moduleName, moduleName));
final Method method = moduleClass.getMethod(INIT_CONSTANTS_METHOD); final Method method = moduleClass.getMethod(INIT_CONSTANTS_METHOD);
if (method != null) { if (method != null) {
method.invoke(this); method.invoke(this);
} }
} catch (Exception ex) { } catch (Exception ex) {
// ignore
} }
} }

View File

@ -1,6 +1,7 @@
package com.annimon.ownlang.parser.linters; package com.annimon.ownlang.parser.linters;
import com.annimon.ownlang.Console; import com.annimon.ownlang.Console;
import com.annimon.ownlang.lib.ArrayValue;
import com.annimon.ownlang.lib.Types; import com.annimon.ownlang.lib.Types;
import com.annimon.ownlang.lib.Value; import com.annimon.ownlang.lib.Value;
import com.annimon.ownlang.parser.ast.*; import com.annimon.ownlang.parser.ast.*;
@ -23,9 +24,26 @@ public final class UseWithNonStringValueValidator extends LintVisitor {
} }
final Value value = ((ValueExpression) st.expression).value; final Value value = ((ValueExpression) st.expression).value;
if (value.type() != Types.STRING) { switch (value.type()) {
Console.error(String.format( case Types.STRING:
"Warning: `use` with %s - %s, not string", Types.typeToString(value.type()), value.asString())); // ok
break;
case Types.ARRAY:
// ok, need additional check
for (Value module : ((ArrayValue) value)) {
if (module.type() != Types.STRING) {
warnWrongType(module);
}
}
break;
default:
warnWrongType(value);
} }
} }
private void warnWrongType(Value value) {
Console.error(String.format(
"Warning: `use` with %s - %s, not string",
Types.typeToString(value.type()), value.asString()));
}
} }

View File

@ -1,6 +1,4 @@
use "base64" use ["base64", "functional", "types"]
use "functional"
use "types"
base64Example = [0x42, 0x61, 0x73, 0x65, 0x36, 0x34, 0x20, 0x45, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65] base64Example = [0x42, 0x61, 0x73, 0x65, 0x36, 0x34, 0x20, 0x45, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65]
base64Example_enc = [0x51, 0x6D, 0x46, 0x7A, 0x5A, 0x54, 0x59, 0x30, base64Example_enc = [0x51, 0x6D, 0x46, 0x7A, 0x5A, 0x54, 0x59, 0x30,

View File

@ -1,5 +1,4 @@
use "files" use ["files", "types"]
use "types"
def testFiles() { def testFiles() {
// writeLong // writeLong

View File

@ -1,6 +1,4 @@
use "std" use ["std", "functional", "math"]
use "functional"
use "math"
def testStream() { def testStream() {
data = [1,2,3,4,5,6,7] data = [1,2,3,4,5,6,7]

View File

@ -1,5 +1,4 @@
use "std" use ["std", "java"]
use "java"
def testCheckNull() { def testCheckNull() {
assertTrue(isNull(null)) assertTrue(isNull(null))

View File

@ -1,6 +1,4 @@
use "std" use ["std", "types", "functional"]
use "types"
use "functional"
def testRangeParams() { def testRangeParams() {
x = range(10) x = range(10)

View File

@ -1,24 +1,22 @@
use "std" use ["std", "yaml", "ounit"]
use "yaml"
use "ounit"
x = yamldecode(" x = yamldecode("
name: \"std\" name: \"std\"
scope: \"both\" scope: \"both\"
desc: \"Contains common functions\" desc: \"Contains common functions\"
desc_ru: \"Содержит вспомогательные функции общего назначения\" desc_ru: \"Содержит вспомогательные функции общего назначения\"
constants: [] constants: []
functions: functions:
- -
name: \"arrayCombine\" name: \"arrayCombine\"
args: \"keys, values\" args: \"keys, values\"
desc: \"creates map by combining two arrays\" desc: \"creates map by combining two arrays\"
desc_ru: \"создаёт объект на основе двух массивов\" desc_ru: \"создаёт объект на основе двух массивов\"
- -
name: \"typeof\" name: \"typeof\"
args: \"value\" args: \"value\"
desc: \"returns the type of value\" desc: \"returns the type of value\"
desc_ru: \"возвращает тип переданного значения\" desc_ru: \"возвращает тип переданного значения\"
example: |- example: |-
print typeof(1) // 1 (NUMBER) print typeof(1) // 1 (NUMBER)
print typeof(\"text\") // 2 (STRING) print typeof(\"text\") // 2 (STRING)
@ -30,4 +28,4 @@ assertEquals("both", x.scope)
assertEquals(0, length(x.constants)) assertEquals(0, length(x.constants))
assertEquals(2, length(x.functions)) assertEquals(2, length(x.functions))
assertEquals("arrayCombine", x.functions[0].name) assertEquals("arrayCombine", x.functions[0].name)
assertEquals("возвращает тип переданного значения", x.functions[1].desc_ru) assertEquals("возвращает тип переданного значения", x.functions[1].desc_ru)

View File

@ -1,6 +1,4 @@
use "std" use ["std", "yaml", "ounit"]
use "yaml"
use "ounit"
yml = yamlencode({ yml = yamlencode({
"name": "Yaml Example", "name": "Yaml Example",