Coder Social home page Coder Social logo

objectionary / dejump Goto Github PK

View Code? Open in Web Editor NEW
10.0 2.0 3.0 430 KB

Replaces all GOTO objects in EO program with semantically equivalent ones but without GOTO

License: MIT License

TeX 19.36% Java 24.63% XSLT 52.30% Groovy 3.71%
eolang java

dejump's Introduction

logo

EO principles respected here DevOps By Rultor.com We recommend IntelliJ IDEA

mvn-linux PDD status Maven Central Hits-of-Code Lines of code License

Takes as an input a program in EO and converts it to a semantically equivalent program, excluding the use of goto object. The input data is a program in .eo/.xmir format, as the output the program returns .eo/.xmir respectively.

Usage

To use this program, the first step is to download the JAR. Then:

$ java -jar target/dejump-1.0-SNAPSHOT-jar-with-dependencies.jar --help

An application has a CLI (Command line interface), which appears as:

Usage: dejump [-hV] [--eo] <file>
Replaces objects GOTO with semantically equivalent
      <file>      Absolute path of file to transform
      --eo        treat input file as EO program (not XMIR)
  -h, --help      Show this help message and exit.
  -V, --version   Print version information and exit.

Depending on the input file format, the output file format will be similar. By default, the input file format is .xmir.

In the directory that contains the file passed as a parameter, a new directory generated is created, in which, after the program is executed, the transformed file will be located.

Example

For the following .eo-code, which appears at temp/example.eo:

[] > example
  memory 0 > x
  goto > @
    [g]
      seq > @
        x.write (x.plus 1)
        if.
          x.eq 5
          g.forward x
          QQ.io.stdout "Again\n"
        g.backward

After the application is executed, the file temp/generated/example_transformed.eo will be created:

[] > example
  memory 0 > x
  seq > @
    flag_fwd.write -1
    flag_bwd.write 0
    while. > g_rem!
      or.
        flag_fwd.eq -1
        flag_bwd.eq 0
      [i]
        seq > @
          flag_fwd.write 0
          flag_bwd.write 1
          seq
            x.write (x.plus 1)
            if.
              x.eq 5
              flag_fwd.write 2
              QQ.io.stdout "Again\n"
            if.
              flag_fwd.eq 0
              flag_bwd.write 0
              TRUE
    if.
      flag_fwd.eq 2
      x
      g_rem
  memory -1 > flag_fwd
  memory 0 > flag_bwd

How to Contribute

You will need JDK 11+ and Maven 3.8+. Clone the repo and run the build like this:

$ mvn clean install -Pqulice

There are .eo files in src/test/eo/org/eolang/dejump, which you can edit or add your own source there. There are the following build steps that process these files:

  1. At generate-test-sources Maven phase, gmavenplus-plugin takes all .eo sources and generates new ones. The files that it generates are not just .eo programs, but EO tests, which combine the code originally taken from original EO programs with the EO code generated. Thus, for src/test/eo/org/eolang/dejump/alpha.eo a modified EO source will be saved into target/eo-after/process_alpha-test.eo.

  2. At process-test-sources phase, eo-maven-plugin process generated .eo files from target/eo-after directory and runs them as junit-tests.

All generated .eo junit-tests are deployed to gh-pages.

dejump's People

Contributors

graur avatar mikhaillipanin avatar renovate[bot] avatar rultor avatar yegor256 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

dejump's Issues

Paper

TODO:

  • update SG/FJ/BJ/TW 's logic
  • update EO/C++ code snippets
  • SG proof
  • FJ proof
  • BJ proof
  • GTW proof

Skeleton

  1. Introduction
  2. Related work
  3. Definitions and Designations
  4. Sample
  5. Method
    5.1. Simple goto
    5.2. Goto forward
    5.3. Goto to While
    5.4. Goto backward
  6. Restrictions
  7. Toolkit
  8. Discussion
    7.1. Necessity and sufficiency
  9. Conclusion
  10. References

build is not automated

Let's automate it, using GitHub Actions. See how it's done in objectionary/eo project, for example, in .github/workflows directory.

XMIR to XMIR doesn't work well

this one:

 <objects>
    <o abstract="" line="1" name="easy_test_case" pos="0">
       <o base="org.eolang.goto" line="2" name="@" pos="2">
          <o abstract="" line="3" pos="4">
             <o line="3" name="g" pos="5"/>
             <o base="org.eolang.seq" line="4" name="@" pos="6">
                <o base=".if" line="5" pos="8">
                   
                   <o base=".lt" line="6" pos="11">
                      <o base="org.eolang.int" data="int" line="6" pos="10">4</o>
                      <o base="org.eolang.int" data="int" line="6" pos="15">5</o>
                   </o>
                   
                   <o base=".forward" line="7" pos="11">
                      <o base="g" line="7" pos="10" ref="3"/>
                      <o base="org.eolang.int" data="int" line="7" pos="20">1337</o>
                   </o>
                   <o base="org.eolang.int" data="int" line="8" pos="10">13</o>
                </o>
                <o base="org.eolang.int" data="int" line="9" pos="8">229</o>
             </o>
          </o>
       </o>
    </o>
 </objects>

maps to:

 <objects>
    <o abstract="" line="1" name="easy_test_case" pos="0">
       <o base="seq" name="@">
          <o base=".write">
             <o base="flag_temp_w23aab3aa"/>
             <o base="int" data="int">0</o>
          </o>
          <o base=".while" const="" name="g_w13aab3aa">
             <o base=".eq">
                <o base="flag_temp_w23aab3aa"/>
                <o base="int" data="int">0</o>
             </o>
             <o abstract="">
                <o name="i"/>
                <o base="seq" name="@">
                   <o base=".write">
                      <o base="flag_temp_w23aab3aa"/>
                      <o base="int" data="int">1</o>
                   </o>
                </o>
             </o>
          </o>
       </o>
       <o base="memory" name="flag_temp_w23aab3aa">
          <o base="int" data="int">0</o>
       </o>
    </o>
 </objects>

which is wrong!

`master` branch

Right now we cannot add some common checks because of the wrong branch name: main.
We need to create the master branch and make it default

newline in samples for tests leads to an error

When I write some sample in src/test/eo/org/eolang/dejump and add a newline in the end of the file it will lead to an error:

Caused by: org.eolang.parser.ParsingException: [19:4] extraneous input '\n    ' expecting {COMMENT, 'Q', 'QQ', '*', '...', '&', '$', '[', '(', '@', '^', BYTES, BOOL, STRING, INT, FLOAT, HEX, NAME, TEXT, UNTAB}: "    "

It seems when we build tests this extra newline space break parser rules and add it before $.equal-to matcher.

RemoveGoto.java:134-135: Configure slf4j Logger and...

The puzzle 54-13754047 from #54 has to be resolved:

@todo #54:30min Configure slf4j Logger and replace these line to Logger.debug
*/

The puzzle was created by @MikhailLipanin on 03-Oct-22.

Estimate: 30 minutes, role: DEV.

If you have any technical questions, don't ask me, submit new tickets instead. The task will be "done" when the problem is fixed and the text of the puzzle is removed from the source code. Here is more about PDD and about me.

MainTest.java:42-44: Rewrite for loop in fullRun method...

The puzzle 52-b84f6231 from #52 has to be resolved:

* @todo #52:30min Rewrite for loop in fullRun method
* as OOP-style of applying functions and comparing
* results in MatcherAssert

The puzzle was created by @MikhailLipanin on 24-Oct-22.

Estimate: 30 minutes, role: DEV.

If you have any technical questions, don't ask me, submit new tickets instead. The task will be "done" when the problem is fixed and the text of the puzzle is removed from the source code. Here is more about PDD and about me.

rultor merge didn't work correctly

    > @rultor merge

@Graur @MikhailLipanin Oops, I failed. You can see the full log here (spent 14s)

+ set -e
+ set -o pipefail
++ dirname ./run.sh
+ cd .
+ echo 1758131
+ echo '2.0-SNAPSHOT BUILD'
2.0-SNAPSHOT BUILD
+ date
Mon 24 Oct 2022 01:33:45 PM CEST
+ uptime
 13:33:45 up 117 days, 15:34,  0 users,  load average: 0.06, 0.03, 0.03
+ cat
com.rultor.spi.Profile: There is no 'merge' section in .rultor.yml
	at com.rultor.agents.req.StartsRequest.docker(StartsRequest.java:350)
	at com.rultor.agents.req.StartsRequest.vars(StartsRequest.java:255)
	at com.rultor.agents.req.StartsRequest.script(StartsRequest.java:148)
	at com.rultor.agents.req.StartsRequest.process(StartsRequest.java:109)
	at com.rultor.agents.AbstractAgent.execute(AbstractAgent.java:70)
	at com.rultor.spi.Agent.execute(Agent.java:84)
	at com.rultor.Routine.process(Routine.java:200)
	at com.rultor.Routine.safe_aroundBody0(Routine.java:178)
	at com.rultor.Routine.run(Routine.java:1)
	at org.aspectj.runtime.reflect.JoinPointImpl.proceed(JoinPointImpl.java:179)
	at com.jcabi.aspects.aj.MethodInterrupter.wrap(MethodInterrupter.java:108)
	at com.rultor.Routine.safe(Routine.java:173)
	at com.rultor.Routine.run(Routine.java:141)
	at com.jcabi.log.VerboseRunnable.run(VerboseRunnable.java:190)
	at com.jcabi.aspects.aj.MethodScheduler.lambda./run.sh(MethodScheduler.java:194)
	at java.base/java.util.concurrent.Executors.call(Executors.java:539)
	at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor.run(ScheduledThreadPoolExecutor.java:305)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor.run(ThreadPoolExecutor.java:635)
	at com.jcabi.log.VerboseThreads.run(VerboseThreads.java:222)
	at java.base/java.lang.Thread.run(Thread.java:833)

+ exit -1
'cid' file is absent, most probably the Docker container wasn't started correctly

Originally posted by @rultor in #73 (comment)

Make XSL-s simplier

I believe, that XSL-s can be much easier than they are now.
It is just an enhancement

to add latex check to github workflows

We need to add a paper checks (latexmk.yml) similar to how we do it in EO:

name: latexmk
on:
  push:
    branches: master
    paths: 'paper/**'
  pull_request:
    branches: master
    paths: 'paper/**'
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: yegor256/[email protected]
        with:
          path: paper
          opts: -pdf
          packages: acmart cjk ffcode href-ul datetime fmtcount libertine paralist makecell footmisc currfile enumitem wrapfig lastpage biblatex titling svg trimspaces catchfile transparent textpos fvextra xstring framed environ totpages hyperxmp ifmtarg ncctools comment anyfontsize fdsymbol algpseudocodex algorithmicx stmaryrd preprint cyrillic cm-super babel-russian hyphen-russian lh to-be-determined cancel iexec csquotes

Need more EO-tests

You can add your .eo tests to src/test/eo/org/eolang/dejump.
Rules for tests:

  • has only one outer abstract object, inside of which the logic of the test;
  • name of this object should be equal to the name of file with this test:
    for example, if your test has a "main" object [] > easy_test, so the .eo file should be called easy_test.eo;
  • your test should not contain any alias-es:
    for example, if you use object stdout in your code, use it as QQ.io.stdout, NOT with alias;
  • logic of your test can be absolutely different - it is no requirement to has a goto object inside, but, since
    we check goto elimination, it would be better that your test will have it :) ;
  • based on concept of transformations, there are cases of using goto, which are not allowed for this applications:
  1. When objects forward/backward encapsulated (directly or throw other objects) in any foreign objects -- objects, that
    are implemented somewhere in your code (objects, that general EO-syntax doesn't support):
goto
  [g]
    foreign_obj > @
      QQ.io.stdout
        "We don't know the logic\n"
      g.forward TRUE
  1. Cases, where we dataize objects forward/backward outside object goto:
goto
  [g]
    seq > @
      foo g
[x] > foo
  x.forward 25

As examples of tests, check .eo files at src/test/eo/org/eolang/dejump.

Rewrite GOTO FORWARD transformation

Now it works like that:

while.
  cond
  [i]
    seq > @
      ...
      if.
        ...
        seq
          k
          flag.write 0
        ...

need to change implementation, so it will works like:

while.
  cond
  [i]
    seq > @
      ...
      if.
        ...
        flag.write 0
        ...
if.
  flag.eq 1
  k

to remove `+alias org.eolang.goto` after transformation

I tried to remove goto object from EO code, translated from C++. So this C++ code:

int check(int x) {
    return 42 / x;
}

I translated via c2eo to this EO code with goto object:

+alias c2eo.coperators.null-function
+alias c2eo.coperators.address
+alias c2eo.coperators.div
+alias org.eolang.goto
+alias c2eo.coperators.plus
+alias c2eo.coperators.ram
+alias c2eo.coperators.read-as-int32
+alias c2eo.coperators.write-as-int32

+package c2eo.src.global
[args...] > global
  $ > root
  ram > global-ram
    8192
  memory > empty-global-position
  ram > return-ram
    8192
  memory > return-mem_size
  address > return
    return-ram
    0
  [param-start param-size] > f-check
    plus > local-start
      param-start
      param-size
    plus > empty-local-position
      local-start
      0
    address > p-x
      global-ram
      plus
        param-start
        0
    goto > @
      [goto-return-label]
        seq > @
          write-as-int32
            return
            div
              42
              read-as-int32
                p-x
          goto-return-label.forward TRUE
          TRUE
  [index param-start param-size] > call
    at. > @
      *
        null-function param-start param-size
        f-check param-start param-size
      index
  seq > @
    TRUE

After that I run dejump and get this EO code:

+alias c2eo.coperators.null-function
+alias c2eo.coperators.address
+alias c2eo.coperators.div
+alias org.eolang.goto
+alias c2eo.coperators.plus
+alias c2eo.coperators.ram
+alias c2eo.coperators.read-as-int32
+alias c2eo.coperators.write-as-int32
+package c2eo.src.global

[args...] > global
  $ > root
  ram > global-ram
    8192
  memory > empty-global-position
  ram > return-ram
    8192
  memory > return-mem_size
  address > return
    return-ram
    0
  [param-start param-size] > f-check
    plus > local-start
      param-start
      param-size
    plus > empty-local-position
      local-start
      0
    address > p-x
      global-ram
      plus
        param-start
        0
    seq > @
      flag_w7aab4ab7b5ab1b1
      .write
        -1
      flag_w7aab4ab7b5ab1b1
      .eq
        -1
      .or
      .while > g_w10aab4ab7b5!
        [i]
          seq > @
            flag_w7aab4ab7b5ab1b1
            .write
              0
            seq
              write-as-int32
                return
                div
                  42
                  read-as-int32
                    p-x
              TRUE
              .if
                seq
                  flag_w7aab4ab7b5ab1b1
                  .write
                    2
                TRUE
              flag_w7aab4ab7b5ab1b1
              .eq
                0
              .if
                seq
                  TRUE
                TRUE
      flag_w7aab4ab7b5ab1b1
      .eq
        2
      .if
        TRUE
        g_w10aab4ab7b5
  [index param-start param-size] > call
    *
      null-function
        param-start
        param-size
      f-check
        param-start
        param-size
    .at > @
      index
  seq > @
    TRUE
  memory > flag_w7aab4ab7b5ab1b1
    -1

And after running this code It was fail with exception unused-aliases:

      <error check="unused-aliases"
              line="6"
              severity="error"
              sheet="unused-aliases"
              step="0">The alias "org.eolang.goto" is not used</error>

Maybe we need to remove this alias in transformed file?

MainTest.java:75-118: Rewrite as OOP-style of applying...

The puzzle 52-0474ee38 from #52 has to be resolved:

@todo #52:30min Rewrite as OOP-style of applying functions and comparing
results in MatcherAssert
*/
for (int idx = 0; idx < first.size(); idx++) {
if (first.get(idx).contains("flag_")) {
first.set(
idx,
String.format(
"%sflag",
first.get(idx).substring(0, first.get(idx).indexOf("flag_"))
)
);
second.set(
idx,
String.format(
"%sflag",
second.get(idx).substring(0, second.get(idx).indexOf("flag_"))
)
);
}
if (first.get(idx).contains("g_")) {
first.set(
idx,
String.format(
"%srem",
first.get(idx).substring(0, first.get(idx).indexOf("g_"))
)
);
second.set(
idx,
String.format(
"%srem",
second.get(idx).substring(0, second.get(idx).indexOf("g_"))
)
);
}
}
MatcherAssert.assertThat(
first,
Matchers.is(second)
);
}
}

The puzzle was created by @MikhailLipanin on 29-Sep-22.

Estimate: 30 minutes, role: DEV.

If you have any technical questions, don't ask me, submit new tickets instead. The task will be "done" when the problem is fixed and the text of the puzzle is removed from the source code. Here is more about PDD and about me.

Project is not running on MacOs

In RemoveGoto.java there are some places like this:

final File dir = new File(
            String.format(
                "%s\\generated",
                this.path.substring(0, this.path.lastIndexOf('\\'))
            )
        );

That try to find path to directory using \ slash, but on MacOs access to files is performed using /. After changing all backslash to front project works good.

rewrite 'flags-to-memory.xsl'

flags should be initialized before each goto (while.) objects:

seq
  flag.write -1
  flag.write ...
  while.
    or.
      ...
    [i]
      seq > @
        ...

RemoveGoto.java:45-46: add RemoveGotoTest */

The puzzle 54-9dfd549f from #54 has to be resolved:

@todo #54:30min add RemoveGotoTest
*/

The puzzle was created by @MikhailLipanin on 03-Oct-22.

Estimate: 30 minutes, role: DEV.

If you have any technical questions, don't ask me, submit new tickets instead. The task will be "done" when the problem is fixed and the text of the puzzle is removed from the source code. Here is more about PDD and about me.

to add qulice checks for the build pipline

Right now I have an error when I run: mvn clean install -Pqulice:

Caused by: java.lang.IllegalArgumentException
    at org.objectweb.asm.ClassReader.<init> (Unknown Source)
    at org.objectweb.asm.ClassReader.<init> (Unknown Source)
    at org.objectweb.asm.ClassReader.<init> (Unknown Source)
    at org.apache.maven.shared.dependency.analyzer.asm.DependencyClassFileVisitor.visitClass (DependencyClassFileVisitor.java:65)
    at org.apache.maven.shared.dependency.analyzer.ClassFileVisitorUtils.visitClass (ClassFileVisitorUtils.java:163)
    at org.apache.maven.shared.dependency.analyzer.ClassFileVisitorUtils.acceptDirectory (ClassFileVisitorUtils.java:143)
    at org.apache.maven.shared.dependency.analyzer.ClassFileVisitorUtils.accept (ClassFileVisitorUtils.java:71)
    at org.apache.maven.shared.dependency.analyzer.asm.ASMDependencyAnalyzer.analyze (ASMDependencyAnalyzer.java:50)
    at org.apache.maven.shared.dependency.analyzer.DefaultProjectDependencyAnalyzer.buildDependencyClasses (DefaultProjectDependencyAnalyzer.java:196)
    at org.apache.maven.shared.dependency.analyzer.DefaultProjectDependencyAnalyzer.buildDependencyClasses (DefaultProjectDependencyAnalyzer.java:183)
    at org.apache.maven.shared.dependency.analyzer.DefaultProjectDependencyAnalyzer.analyze (DefaultProjectDependencyAnalyzer.java:74)
    at com.qulice.maven.DependenciesValidator.analyze (DependenciesValidator.java:127)
    at com.qulice.maven.DependenciesValidator.unused (DependenciesValidator.java:156)
    at com.qulice.maven.DependenciesValidator.validate (DependenciesValidator.java:75)
    at com.qulice.maven.CheckMojo.run (CheckMojo.java:149)
    at com.qulice.maven.CheckMojo.doExecute (CheckMojo.java:79)
    at com.qulice.maven.AbstractQuliceMojo.execute (AbstractQuliceMojo.java:170)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:301)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:211)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:165)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:157)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:121)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:127)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:294)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)

To fix it we need to find out what why is this happens

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Rate-Limited

These updates are currently rate-limited. Click on a checkbox below to force their creation now.

  • Update actions/cache action to v4
  • Update actions/setup-java action to v4
  • Update dependency ubuntu to v22
  • ๐Ÿ” Create all rate-limited PRs at once ๐Ÿ”

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/build.yml
  • actions/checkout v4
  • actions/setup-java v3
  • actions/cache v3
.github/workflows/gh-pages.yml
  • actions/checkout v4
  • actions/setup-java v3
  • JamesIves/github-pages-deploy-action v4.4.1
.github/workflows/pdd.yml
  • actions/checkout v4
  • ubuntu 22.04
.github/workflows/xcop.yml
  • actions/checkout v4
  • ubuntu 20.04
maven
pom.xml
  • com.jcabi:parent 0.65.0
  • org.eolang:eo-parser 0.28.18
  • com.jcabi:jcabi-xml 0.27.2
  • org.cactoos:cactoos 0.55.0
  • com.yegor256:xsline 0.20.1
  • org.yaml:snakeyaml 1.33
  • info.picocli:picocli 4.7.1
  • org.apache.maven.plugins:maven-compiler-plugin 3.8.1
  • org.codehaus.gmavenplus:gmavenplus-plugin 2.1.0
  • org.codehaus.groovy:groovy 3.0.15
  • org.eolang:eo-maven-plugin 0.28.18

  • Check this box to trigger a request for Renovate to run again on this repository

generate.groovy:35: Resolve all tests, that are blocked...

The puzzle 5-f89f8d5a from #5 has to be resolved:

* @todo #5:90min Resolve all tests, that are blocked due "todo" array.

The puzzle was created by @MikhailLipanin on 23-Dec-22.

Estimate: 90 minutes, role: DEV.

If you have any technical questions, don't ask me, submit new tickets instead. The task will be "done" when the problem is fixed and the text of the puzzle is removed from the source code. Here is more about PDD and about me.

flags-to-memory.xsl:9-10: Add template for objects before...

The puzzle 25-cede29ff from #25 has to be resolved:

@todo #25:30m Add template for objects before that ones,
that has attribute @uniq.

The puzzle was created by Mikhail Lipanin on 07-Sep-22.

Estimate: 30 minutes, role: DEV.

If you have any technical questions, don't ask me, submit new tickets instead. The task will be "done" when the problem is fixed and the text of the puzzle is removed from the source code. Here is more about PDD and about me.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.