Skip to content

Commit 31b4539

Browse files
committed
Добавлен модуль yaml
1 parent 29d40a5 commit 31b4539

File tree

7 files changed

+235
-0
lines changed

7 files changed

+235
-0
lines changed

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ dependencies {
5757
exclude group: 'org.json', module: 'json'
5858
}
5959
compile 'org.json:json:20160212'
60+
compile 'org.yaml:snakeyaml:1.17'
6061

6162
testCompile 'junit:junit:4.12'
6263
testCompile 'org.openjdk.jmh:jmh-core:1.13'

examples/formats/yaml.own

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use "yaml"
2+
3+
println "Yaml encode"
4+
println yamlencode({
5+
"name": "Yaml Example",
6+
"version": 1,
7+
"arrayData": [
8+
1, 2, 3, 4
9+
],
10+
"objectData": {
11+
"key": "value",
12+
10: "1000"
13+
}
14+
})
15+
16+
println "\nYaml decode"
17+
x = yamldecode("
18+
name: \"std\"
19+
scope: \"both\"
20+
desc: \"Contains common functions\"
21+
desc_ru: \"Содержит вспомогательные функции общего назначения\"
22+
constants: []
23+
functions:
24+
-
25+
name: \"arrayCombine\"
26+
args: \"keys, values\"
27+
desc: \"creates map by combining two arrays\"
28+
desc_ru: \"создаёт объект на основе двух массивов\"
29+
-
30+
name: \"typeof\"
31+
args: \"value\"
32+
desc: \"returns the type of value\"
33+
desc_ru: \"возвращает тип переданного значения\"
34+
example: |-
35+
print typeof(1) // 1 (NUMBER)
36+
print typeof(\"text\") // 2 (STRING)
37+
print typeof([]) // 3 (ARRAY)
38+
")
39+
println x.name + ", scope: " + x.scope
40+
println x.desc
41+
for func : x.functions {
42+
println " - " + func.name + "(" + func.args + ")"
43+
println " " + func.desc
44+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.annimon.ownlang.modules.yaml;
2+
3+
import com.annimon.ownlang.lib.*;
4+
import com.annimon.ownlang.modules.Module;
5+
6+
/**
7+
*
8+
* @author aNNiMON
9+
*/
10+
public final class yaml implements Module {
11+
12+
@Override
13+
public void init() {
14+
Functions.set("yamlencode", new yaml_encode());
15+
Functions.set("yamldecode", new yaml_decode());
16+
}
17+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.annimon.ownlang.modules.yaml;
2+
3+
import com.annimon.ownlang.lib.*;
4+
import java.util.List;
5+
import java.util.Map;
6+
import org.yaml.snakeyaml.Yaml;
7+
8+
public final class yaml_decode implements Function {
9+
10+
@Override
11+
public Value execute(Value... args) {
12+
Arguments.check(1, args.length);
13+
try {
14+
final String yamlRaw = args[0].asString();
15+
final Object root = new Yaml().load(yamlRaw);
16+
final Value process = process(root);
17+
return process;
18+
} catch (Exception ex) {
19+
throw new RuntimeException("Error while parsing yaml", ex);
20+
}
21+
}
22+
23+
private Value process(Object obj) {
24+
if (obj instanceof Map) {
25+
return process((Map) obj);
26+
}
27+
if (obj instanceof List) {
28+
return process((List) obj);
29+
}
30+
if (obj instanceof String) {
31+
return new StringValue((String) obj);
32+
}
33+
if (obj instanceof Number) {
34+
return NumberValue.of(((Number) obj));
35+
}
36+
if (obj instanceof Boolean) {
37+
return NumberValue.fromBoolean((Boolean) obj);
38+
}
39+
// NULL or other
40+
return NumberValue.ZERO;
41+
}
42+
43+
private MapValue process(Map<Object, Object> map) {
44+
final MapValue result = new MapValue(map.size());
45+
for (Map.Entry<Object, Object> entry : map.entrySet()) {
46+
final String key = entry.getKey().toString();
47+
final Value value = process(entry.getValue());
48+
result.set(new StringValue(key), value);
49+
}
50+
return result;
51+
}
52+
53+
private ArrayValue process(List list) {
54+
final int length = list.size();
55+
final ArrayValue result = new ArrayValue(length);
56+
for (int i = 0; i < length; i++) {
57+
final Value value = process(list.get(i));
58+
result.set(i, value);
59+
}
60+
return result;
61+
}
62+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.annimon.ownlang.modules.yaml;
2+
3+
import com.annimon.ownlang.lib.*;
4+
import java.util.ArrayList;
5+
import java.util.HashMap;
6+
import java.util.List;
7+
import java.util.Map;
8+
import org.yaml.snakeyaml.Yaml;
9+
10+
public final class yaml_encode implements Function {
11+
12+
@Override
13+
public Value execute(Value... args) {
14+
Arguments.check(1, args.length);
15+
try {
16+
final Object root = process(args[0]);
17+
final String yamlRaw = new Yaml().dump(root);
18+
return new StringValue(yamlRaw);
19+
} catch (Exception ex) {
20+
throw new RuntimeException("Error while creating yaml", ex);
21+
}
22+
}
23+
24+
private Object process(Value val) {
25+
switch (val.type()) {
26+
case Types.ARRAY:
27+
return process((ArrayValue) val);
28+
case Types.MAP:
29+
return process((MapValue) val);
30+
case Types.NUMBER:
31+
return val.raw();
32+
case Types.STRING:
33+
return val.asString();
34+
default:
35+
return null;
36+
}
37+
}
38+
39+
private Object process(MapValue map) {
40+
final Map<String, Object> result = new HashMap<>();
41+
for (Map.Entry<Value, Value> entry : map) {
42+
final String key = entry.getKey().asString();
43+
final Object value = process(entry.getValue());
44+
result.put(key, value);
45+
}
46+
return result;
47+
}
48+
49+
private Object process(ArrayValue array) {
50+
final List<Object> result = new ArrayList<>();
51+
for (Value value : array) {
52+
result.add(process(value));
53+
}
54+
return result;
55+
}
56+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
use "std"
2+
use "yaml"
3+
use "ounit"
4+
5+
x = yamldecode("
6+
name: \"std\"
7+
scope: \"both\"
8+
desc: \"Contains common functions\"
9+
desc_ru: \"�������� ��������������� ������� ������ ����������\"
10+
constants: []
11+
functions:
12+
-
13+
name: \"arrayCombine\"
14+
args: \"keys, values\"
15+
desc: \"creates map by combining two arrays\"
16+
desc_ru: \"������ ������ �� ������ ���� ��������\"
17+
-
18+
name: \"typeof\"
19+
args: \"value\"
20+
desc: \"returns the type of value\"
21+
desc_ru: \"���������� ��� ����������� ��������\"
22+
example: |-
23+
print typeof(1) // 1 (NUMBER)
24+
print typeof(\"text\") // 2 (STRING)
25+
print typeof([]) // 3 (ARRAY)
26+
")
27+
28+
assertEquals("std", x.name)
29+
assertEquals("both", x.scope)
30+
assertEquals(0, length(x.constants))
31+
assertEquals(2, length(x.functions))
32+
assertEquals("arrayCombine", x.functions[0].name)
33+
assertEquals("���������� ��� ����������� ��������", x.functions[1].desc_ru)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use "std"
2+
use "yaml"
3+
use "ounit"
4+
5+
yml = yamlencode({
6+
"name": "Yaml Example",
7+
"version": 1,
8+
"arrayData": [
9+
1, 2, 3, 4
10+
],
11+
"objectData": {
12+
"key": "value",
13+
10: "1000"
14+
}
15+
})
16+
obj = yamldecode(yml)
17+
18+
assertEquals("Yaml Example", obj.name)
19+
assertEquals(1, obj.version)
20+
assertEquals(4, length(obj.arrayData))
21+
assertEquals("value", obj.objectData.key)
22+
assertEquals("1000", obj.objectData["10"])

0 commit comments

Comments
 (0)