Добавлен модуль yaml

This commit is contained in:
Victor 2016-09-16 17:32:35 +03:00
parent 29d40a554f
commit 31b4539fd8
7 changed files with 235 additions and 0 deletions

View File

@ -57,6 +57,7 @@ dependencies {
exclude group: 'org.json', module: 'json' exclude group: 'org.json', module: 'json'
} }
compile 'org.json:json:20160212' compile 'org.json:json:20160212'
compile 'org.yaml:snakeyaml:1.17'
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
testCompile 'org.openjdk.jmh:jmh-core:1.13' testCompile 'org.openjdk.jmh:jmh-core:1.13'

44
examples/formats/yaml.own Normal file
View File

@ -0,0 +1,44 @@
use "yaml"
println "Yaml encode"
println yamlencode({
"name": "Yaml Example",
"version": 1,
"arrayData": [
1, 2, 3, 4
],
"objectData": {
"key": "value",
10: "1000"
}
})
println "\nYaml decode"
x = yamldecode("
name: \"std\"
scope: \"both\"
desc: \"Contains common functions\"
desc_ru: \"Содержит вспомогательные функции общего назначения\"
constants: []
functions:
-
name: \"arrayCombine\"
args: \"keys, values\"
desc: \"creates map by combining two arrays\"
desc_ru: \"создаёт объект на основе двух массивов\"
-
name: \"typeof\"
args: \"value\"
desc: \"returns the type of value\"
desc_ru: \"возвращает тип переданного значения\"
example: |-
print typeof(1) // 1 (NUMBER)
print typeof(\"text\") // 2 (STRING)
print typeof([]) // 3 (ARRAY)
")
println x.name + ", scope: " + x.scope
println x.desc
for func : x.functions {
println " - " + func.name + "(" + func.args + ")"
println " " + func.desc
}

View File

@ -0,0 +1,17 @@
package com.annimon.ownlang.modules.yaml;
import com.annimon.ownlang.lib.*;
import com.annimon.ownlang.modules.Module;
/**
*
* @author aNNiMON
*/
public final class yaml implements Module {
@Override
public void init() {
Functions.set("yamlencode", new yaml_encode());
Functions.set("yamldecode", new yaml_decode());
}
}

View File

@ -0,0 +1,62 @@
package com.annimon.ownlang.modules.yaml;
import com.annimon.ownlang.lib.*;
import java.util.List;
import java.util.Map;
import org.yaml.snakeyaml.Yaml;
public final class yaml_decode implements Function {
@Override
public Value execute(Value... args) {
Arguments.check(1, args.length);
try {
final String yamlRaw = args[0].asString();
final Object root = new Yaml().load(yamlRaw);
final Value process = process(root);
return process;
} catch (Exception ex) {
throw new RuntimeException("Error while parsing yaml", ex);
}
}
private Value process(Object obj) {
if (obj instanceof Map) {
return process((Map) obj);
}
if (obj instanceof List) {
return process((List) obj);
}
if (obj instanceof String) {
return new StringValue((String) obj);
}
if (obj instanceof Number) {
return NumberValue.of(((Number) obj));
}
if (obj instanceof Boolean) {
return NumberValue.fromBoolean((Boolean) obj);
}
// NULL or other
return NumberValue.ZERO;
}
private MapValue process(Map<Object, Object> map) {
final MapValue result = new MapValue(map.size());
for (Map.Entry<Object, Object> entry : map.entrySet()) {
final String key = entry.getKey().toString();
final Value value = process(entry.getValue());
result.set(new StringValue(key), value);
}
return result;
}
private ArrayValue process(List list) {
final int length = list.size();
final ArrayValue result = new ArrayValue(length);
for (int i = 0; i < length; i++) {
final Value value = process(list.get(i));
result.set(i, value);
}
return result;
}
}

View File

@ -0,0 +1,56 @@
package com.annimon.ownlang.modules.yaml;
import com.annimon.ownlang.lib.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.yaml.snakeyaml.Yaml;
public final class yaml_encode implements Function {
@Override
public Value execute(Value... args) {
Arguments.check(1, args.length);
try {
final Object root = process(args[0]);
final String yamlRaw = new Yaml().dump(root);
return new StringValue(yamlRaw);
} catch (Exception ex) {
throw new RuntimeException("Error while creating yaml", ex);
}
}
private Object process(Value val) {
switch (val.type()) {
case Types.ARRAY:
return process((ArrayValue) val);
case Types.MAP:
return process((MapValue) val);
case Types.NUMBER:
return val.raw();
case Types.STRING:
return val.asString();
default:
return null;
}
}
private Object process(MapValue map) {
final Map<String, Object> result = new HashMap<>();
for (Map.Entry<Value, Value> entry : map) {
final String key = entry.getKey().asString();
final Object value = process(entry.getValue());
result.put(key, value);
}
return result;
}
private Object process(ArrayValue array) {
final List<Object> result = new ArrayList<>();
for (Value value : array) {
result.add(process(value));
}
return result;
}
}

View File

@ -0,0 +1,33 @@
use "std"
use "yaml"
use "ounit"
x = yamldecode("
name: \"std\"
scope: \"both\"
desc: \"Contains common functions\"
desc_ru: \"Ñîäåðæèò âñïîìîãàòåëüíûå ôóíêöèè îáùåãî íàçíà÷åíèÿ\"
constants: []
functions:
-
name: \"arrayCombine\"
args: \"keys, values\"
desc: \"creates map by combining two arrays\"
desc_ru: \"ñîçäà¸ò îáúåêò íà îñíîâå äâóõ ìàññèâîâ\"
-
name: \"typeof\"
args: \"value\"
desc: \"returns the type of value\"
desc_ru: \"âîçâðàùàåò òèï ïåðåäàííîãî çíà÷åíèÿ\"
example: |-
print typeof(1) // 1 (NUMBER)
print typeof(\"text\") // 2 (STRING)
print typeof([]) // 3 (ARRAY)
")
assertEquals("std", x.name)
assertEquals("both", x.scope)
assertEquals(0, length(x.constants))
assertEquals(2, length(x.functions))
assertEquals("arrayCombine", x.functions[0].name)
assertEquals("âîçâðàùàåò òèï ïåðåäàííîãî çíà÷åíèÿ", x.functions[1].desc_ru)

View File

@ -0,0 +1,22 @@
use "std"
use "yaml"
use "ounit"
yml = yamlencode({
"name": "Yaml Example",
"version": 1,
"arrayData": [
1, 2, 3, 4
],
"objectData": {
"key": "value",
10: "1000"
}
})
obj = yamldecode(yml)
assertEquals("Yaml Example", obj.name)
assertEquals(1, obj.version)
assertEquals(4, length(obj.arrayData))
assertEquals("value", obj.objectData.key)
assertEquals("1000", obj.objectData["10"])