diff --git a/README b/README deleted file mode 100644 index 910bcfe..0000000 --- a/README +++ /dev/null @@ -1,32 +0,0 @@ -The Drift Programming Language Implementation - -- switch CC field in Makefile and specify your g++ compiler path -- my gcc version is 10.2.0 - -To build: - - > make - > make install - -To install: - - > export PATH=$PWD:$PATH - -To run: - - > drift # REPL MODE - > drift # FILE MODE - - > drift -d # REPL AND DEBUG MODE - > drift -d # FILE AND DEBUG MODE - - > drift -b # REPL AND DIS BYTECODE - > drift -b # FILE AND DIS BYTECODE - -To clean: - - > make clean - -For documentation and project architecuture, visit the official website https://drift-lang.fun - -It's a toy language, Have Fun!! diff --git a/README.md b/README.md new file mode 100644 index 0000000..960320d --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +# The Drift Programming Language + +

Refined, minimalist, modern, beautiful

+ +- Fourteen keywords +- Twelve object types +- Bytecode virtual machine + +Basic grammatical format of drift, please check the instance code `awesome.ft` + +## Build + +- switch CC field in Makefile and specify your g++ compiler path +- my gcc version is 10.2.0 + +``` +make +make install +``` + +### To install: + + export PATH=$PWD:$PATH + +### To run: + + drift # REPL MODE + drift # FILE MODE + + drift -d # REPL AND DEBUG MODE + drift -d # FILE AND DEBUG MODE + + drift -b # REPL AND DIS BYTECODE + drift -b # FILE AND DIS BYTECODE + +### To clean: + + make clean + +## Collaborative development + +- Lack of FFI support +- Syntax highlighting support for Virtual Studio Code, `tool` directory +- Standard library and bug testing, etc + +## More + +For documentation and project architecuture, +visit the official website https://drift-lang.fun/ + +**It's a toy language, Have Fun!!** + +## License +``` +Copyright (c) 2021 bingxio(丙杺,黄菁). All rights reserved. + +GNU General Public License, more to see file: LICENSE +https://www.gnu.org/licenses + + THE DRIFT PROGRAMMING LANGUAGE + + https://github.com/bingxio/drift + + https://www.drift-lang.fun/ +``` \ No newline at end of file diff --git a/test/awesome.ft b/awesome.ft similarity index 77% rename from test/awesome.ft rename to awesome.ft index 9c3896d..1ca4c28 100644 --- a/test/awesome.ft +++ b/awesome.ft @@ -27,6 +27,7 @@ 9.enum 10.function 11.whole + 12.module */ /* @@ -151,26 +152,28 @@ end def (x: |int, int| -> int, a + b: int) sum -> int ret x(a, b) + x(a, b) end -/* + def () set -> |int| - ret def (x: int) - ret x * 2 + ret def (x: int) _ /* ANONYMOUSE */ + puts(x * 2) end end -*/ + +set()(8) + def (x: int) bar -> |int, int| -> []int - putl("x = ", x) - - ret def (a + b: int) -> []int - ret [ - a, - b, - a + b, - a - b, - a * b, - a / b - ] - end + putl("x = ", x) + + ret def (a + b: int) -> []int /* ANONYMOUSE */ + ret [ + a, + b, + a + b, + a - b, + a * b, + a / b + ] + end end put( @@ -202,25 +205,40 @@ def Foo end end -def Go - def () *test +putl(new Foo.max(34, 12), new Foo.x, new Foo.y) + +def Kop + def () *more end -def Bar <- Foo + Go - def () test - putl("TEST!!") - end +def Oop <- Foo + Kop /* INHERIT */ + def () more end - def () bar - test() + def () bar + putl(max(99, 98)) /* CALL INHERIT */ end def (x: bool) what -> bool - ret !x + ret T end end -def f: Foo = new Foo{x: 43} -putl(f.x, f.y, f.max(2, 4)) +putl(new Oop.bar()) + +/* + Others: +*/ + +def x: int = 30 +def y: []int = [1, 2, 3] +def z: [3]float + +putl("x = $x y = $y z = $z") + +aop -> + putl("x: $x ") /* STRING TEMPLATE */ + out x == 20 + x -= 1 +end -def b: Bar = new Bar \ No newline at end of file +putl() // END \ No newline at end of file diff --git a/src/ffi.cc b/src/ffi.cc new file mode 100644 index 0000000..bf3004b --- /dev/null +++ b/src/ffi.cc @@ -0,0 +1,15 @@ +// +// Copyright (c) 2021 bingxio(丙杺,黄菁). All rights reserved. +// + +// GNU General Public License, more to see file: LICENSE +// https://www.gnu.org/licenses + +// THE DRIFT PROGRAMMING LANGUAGE +// +// https://github.com/bingxio/drift +// +// https://www.drift-lang.fun/ +// + +#include "ffi.h" \ No newline at end of file diff --git a/src/ffi.h b/src/ffi.h new file mode 100644 index 0000000..aa106cd --- /dev/null +++ b/src/ffi.h @@ -0,0 +1,18 @@ +// +// Copyright (c) 2021 bingxio(丙杺,黄菁). All rights reserved. +// + +// GNU General Public License, more to see file: LICENSE +// https://www.gnu.org/licenses + +// THE DRIFT PROGRAMMING LANGUAGE +// +// https://github.com/bingxio/drift +// +// https://www.drift-lang.fun/ +// + +#ifndef DRIFT_FFI_H +#define DRIFT_FFI_H + +#endif \ No newline at end of file diff --git a/src/lexer.cc b/src/lexer.cc index bffe000..4d591f6 100644 --- a/src/lexer.cc +++ b/src/lexer.cc @@ -123,6 +123,10 @@ void Lexer::lexIdent() { tok.literal = literal.str(); tok.line = this->line; + if (tok.kind == token::IDENT && tok.literal == "_") { + tok.kind = token::UNDERLINE; // single symbol + } + this->tokens.push_back(tok); } diff --git a/src/parser.cc b/src/parser.cc index 62263d8..4395ff5 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -461,8 +461,18 @@ ast::Stmt *Parser::stmt() { } } + // anonymouse function + if (look(token::R_ARROW) || look(token::UNDERLINE)) { + return new ast::FuncStmt( + funcArgs, // argument + token::Token{.kind = token::EFF, .literal = "anonymouse"}, // name + previous().kind == token::R_ARROW ? this->type() + : nullptr, // return + this->block(token::END) // block + ); + } // function - if (look(token::IDENT)) { + else if (look(token::IDENT)) { name = previous(); } // interface @@ -475,12 +485,6 @@ ast::Stmt *Parser::stmt() { // current parsing interface statement interfaceStmt = true; } - // anonymouse function - else if (look(token::R_ARROW)) { - return new ast::FuncStmt( - funcArgs, token::Token{.kind = token::EFF, .literal = "anonymouse"}, - this->type(), this->block(token::END)); - } // error else { error(exp::UNEXPECTED, @@ -772,9 +776,8 @@ Type *Parser::type(bool previous) { continue; } } - if (look(token::R_ARROW)) { - ret = this->type(); - } + + if (look(token::R_ARROW)) ret = this->type(); // return return new Func(arguments, ret); } error(exp::INVALID_SYNTAX, "invalid type"); diff --git a/src/vm.cc b/src/vm.cc index ae4869b..0e1f999 100644 --- a/src/vm.cc +++ b/src/vm.cc @@ -390,12 +390,12 @@ void vm::newWhole(std::string name, int count, bool inner) { } // to check interface of whole -void vm::checkInterface(object::Whole *it, object::Whole *se) { - for (std::tuple i : it->interface) { +void vm::checkInterface(object::Whole *src, object::Whole *dst) { + for (std::tuple i : src->interface) { // TO TABLE SYMBOL std::map::iterator iter; - for (iter = se->f->tb.symbols.begin(); iter != se->f->tb.symbols.end(); + for (iter = dst->f->tb.symbols.begin(); iter != dst->f->tb.symbols.end(); iter++) { // NAME if (iter->first == std::get<0>(i)) { @@ -408,8 +408,14 @@ void vm::checkInterface(object::Whole *it, object::Whole *se) { object::Func *f = static_cast(iter->second); // RETURN - if (f->ret->kind() != std::get<2>(i)->kind()) - error("bad return type for subclass inheritance"); + if (std::get<2>(i) == nullptr && f->ret != nullptr) + error("its not have return type"); + + if (std::get<2>(i) != nullptr) { + if (std::get<2>(i)->kind() != f->ret->kind()) { + error("bad return type for subclass inheritance"); + } + } // ARGUMENT if (std::get<1>(i).size() != f->arguments.size()) error("inconsistent arguments for subclass inheritance"); @@ -431,8 +437,9 @@ void vm::checkInterface(object::Whole *it, object::Whole *se) { } // NOT FOUND - if (iter == se->f->tb.symbols.end()) + if (iter == dst->f->tb.symbols.end()) { error("not inherited method '" + std::get<0>(i) + "' of subclass"); + } } } @@ -451,49 +458,60 @@ void vm::evaluate() { // EVALUATE case byte::CONST: { // CONST object::Object *obj = this->retConstant(); + this->op++; + // STRING TEMPLATE if (obj->kind() == object::STR) { object::Str *s = static_cast(obj); - char *data = s->value.data(); - int count = 0; + char *data = s->value.data(); // CHARS + int count = 0; // COUNT while (*data++ != '\0') if (*data == '$') count++; // GET COUNT OF $ + if (count == 0) { // NONE + PUSH(obj); + break; + } + + object::Str *n = new object::Str(s->value); // NEW + while (count-- > 0) { - for (int i = 0; i < s->value.size(); i++) { - if (s->value.at(i) == '$') { - i++; // SKIP LEFR $ + for (int i = 0; i < n->value.size(); i++) { + if (n->value.at(i) == '$') { + i++; // SKIP LEFT $ // TO NAME - std::string n; + std::string r; // GET NAME - while (i < s->value.size() && isalpha(s->value.at(i))) { - n.push_back(s->value.at(i)); + while (i < n->value.size() && isalpha(n->value.at(i))) { + r.push_back(n->value.at(i)); i++; } - if (n.empty()) error("string template need a ident name"); - object::Object *o = this->lookUp(n); // OBJECT + if (r.empty()) error("string template need a ident name"); + object::Object *o = this->lookUp(r); // OBJECT - if (o == nullptr) error("not defined name '" + n + "'"); + if (o == nullptr) error("not defined name '" + r + "'"); - int p = i - n.size() - 1; // START + int p = i - r.size() - 1; // START - s->value.erase(p, n.size() + 1); // REMOVE - s->value.insert(p, o->stringer()); // INSERT + n->value.erase(p, r.size() + 1); // REMOVE + n->value.insert(p, o->stringer()); // INSERT break; // NEXT } } } + + PUSH(n); + break; } PUSH(obj); - this->op++; } break; // diff --git a/tool/drift-vscode/.vscodeignore b/tool/drift-vscode/.vscodeignore new file mode 100644 index 0000000..f369b5e --- /dev/null +++ b/tool/drift-vscode/.vscodeignore @@ -0,0 +1,4 @@ +.vscode/** +.vscode-test/** +.gitignore +vsc-extension-quickstart.md diff --git a/tool/drift-vscode/CHANGELOG.md b/tool/drift-vscode/CHANGELOG.md new file mode 100644 index 0000000..fa0cc51 --- /dev/null +++ b/tool/drift-vscode/CHANGELOG.md @@ -0,0 +1,9 @@ +# Change Log + +All notable changes to the "drift-vscode" extension will be documented in this file. + +Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. + +## [Unreleased] + +- Initial release \ No newline at end of file diff --git a/tool/drift-vscode/README.md b/tool/drift-vscode/README.md new file mode 100644 index 0000000..3562420 --- /dev/null +++ b/tool/drift-vscode/README.md @@ -0,0 +1,65 @@ +# drift-vscode README + +This is the README for your extension "drift-vscode". After writing up a brief description, we recommend including the following sections. + +## Features + +Describe specific features of your extension including screenshots of your extension in action. Image paths are relative to this README file. + +For example if there is an image subfolder under your extension project workspace: + +\!\[feature X\]\(images/feature-x.png\) + +> Tip: Many popular extensions utilize animations. This is an excellent way to show off your extension! We recommend short, focused animations that are easy to follow. + +## Requirements + +If you have any requirements or dependencies, add a section describing those and how to install and configure them. + +## Extension Settings + +Include if your extension adds any VS Code settings through the `contributes.configuration` extension point. + +For example: + +This extension contributes the following settings: + +* `myExtension.enable`: enable/disable this extension +* `myExtension.thing`: set to `blah` to do something + +## Known Issues + +Calling out known issues can help limit users opening duplicate issues against your extension. + +## Release Notes + +Users appreciate release notes as you update your extension. + +### 1.0.0 + +Initial release of ... + +### 1.0.1 + +Fixed issue #. + +### 1.1.0 + +Added features X, Y, and Z. + +----------------------------------------------------------------------------------------------------------- + +## Working with Markdown + +**Note:** You can author your README using Visual Studio Code. Here are some useful editor keyboard shortcuts: + +* Split the editor (`Cmd+\` on macOS or `Ctrl+\` on Windows and Linux) +* Toggle preview (`Shift+CMD+V` on macOS or `Shift+Ctrl+V` on Windows and Linux) +* Press `Ctrl+Space` (Windows, Linux) or `Cmd+Space` (macOS) to see a list of Markdown snippets + +### For more information + +* [Visual Studio Code's Markdown Support](http://code.visualstudio.com/docs/languages/markdown) +* [Markdown Syntax Reference](https://help.github.com/articles/markdown-basics/) + +**Enjoy!** diff --git a/tool/drift-vscode/language-configuration.json b/tool/drift-vscode/language-configuration.json new file mode 100644 index 0000000..622dc0b --- /dev/null +++ b/tool/drift-vscode/language-configuration.json @@ -0,0 +1,34 @@ +{ + "comments": { + // symbol used for single line comment. Remove this entry if your language does not support line comments + "lineComment": "//", + // symbols used for start and end a block comment. Remove this entry if your language does not support block comments + "blockComment": [ "/*", "*/" ] + }, + // symbols used as brackets + "brackets": [ + ["{", "}"], + ["[", "]"], + ["(", ")"] + ], + // symbols that are auto closed when typing + "autoClosingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""], + ["'", "'"] + ], + // symbols that can be used to surround a selection + "surroundingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""], + ["'", "'"] + ], + "indentationRules": { + "increaseIndentPattern": "(^((\\s*(def|aop|for|if|ef|nf))|(.*\\bdef))\\b((?!\\b(end)\\b).)*)$", + "decreaseIndentPattern": "^\\s*((\\b(ef|nf|end)\\b)|(\\)))" + } +} \ No newline at end of file diff --git a/tool/drift-vscode/package.json b/tool/drift-vscode/package.json new file mode 100644 index 0000000..2e7d862 --- /dev/null +++ b/tool/drift-vscode/package.json @@ -0,0 +1,25 @@ +{ + "name": "drift-vscode", + "displayName": "drift-vscode", + "description": "", + "version": "0.0.1", + "engines": { + "vscode": "^1.55.0" + }, + "categories": [ + "Programming Languages" + ], + "contributes": { + "languages": [{ + "id": "drift", + "aliases": ["Drift", "ft", "drift"], + "extensions": [".ft"], + "configuration": "./language-configuration.json" + }], + "grammars": [{ + "language": "drift", + "scopeName": "source.ft", + "path": "./syntaxes/drift.json" + }] + } +} \ No newline at end of file diff --git a/tool/drift-vscode/syntaxes/drift.json b/tool/drift-vscode/syntaxes/drift.json new file mode 100644 index 0000000..730022f --- /dev/null +++ b/tool/drift-vscode/syntaxes/drift.json @@ -0,0 +1,100 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "drift", + "patterns": [{ + "include": "#keywords" + }, + { + "include": "#strings" + }, + { + "include": "#comment" + }, + { + "include": "#comment-block" + }, + { + "include": "#identifier" + }, + { + "include": "#number" + }, + { + "include": "#operator" + }, + { + "include": "#member" + }, + { + "include": "#function" + } + ], + "repository": { + "keywords": { + "patterns": [{ + "name": "keyword.control.ft", + "match": "\\b(def|if|ef|nf|aop|for|ret|end|mod|new|use|out|go|del)\\b" + }] + }, + "strings": { + "name": "string.quoted.double.ft", + "begin": "\"", + "end": "\"", + "patterns": [{ + "name": "constant.character.escape.ft", + "match": "\\\\." + }] + }, + "comment": { + "name": "comment.line.ft", + "begin": "\\//", + "end": "\\n", + "patterns": [ + {} + ] + }, + "comment-block": { + "name": "comment.block.ft", + "begin": "\\/\\*", + "end": "\\*/", + "patterns": [ + {} + ] + }, + "identifier": { + "patterns": [{ + "name": "identifier.ft", + "match": "\\b[_A-Za-z]\\w+\\b" + }] + }, + "number": { + "patterns": [{ + "name": "constant.numeric.ft", + "match": "0x[a-fA-F0-9]+|\\d+|(\\d+\\.?|\\.\\d)\\d*([eE][+-]?\\d+)?" + }] + }, + "operator": { + "patterns": [{ + "name": "keyword.operator.ft", + "match": "\\(|\\)|\\[|\\]|\\.|-|\\!|~|\\*|/|%|\\+|&|\\^|\\|<|>!=|:" + }] + }, + "member": { + "patterns": [{ + "match": "\\.([a-zA-Z_][a-zA-Z0-9_]*)", + "captures": { + "0": { + "name": "entity.other.attribute-name.ft" + } + } + }] + }, + "function": { + "patterns": [{ + "name": "entity.name.function.ft", + "match": "\\b([a-zA-Z_][a-zA-Z0-9_]*(?=\\s*\\())" + }] + } + }, + "scopeName": "source.ft" +} \ No newline at end of file diff --git a/tool/drift-vscode/vsc-extension-quickstart.md b/tool/drift-vscode/vsc-extension-quickstart.md new file mode 100644 index 0000000..c45a08d --- /dev/null +++ b/tool/drift-vscode/vsc-extension-quickstart.md @@ -0,0 +1,29 @@ +# Welcome to your VS Code Extension + +## What's in the folder + +* This folder contains all of the files necessary for your extension. +* `package.json` - this is the manifest file in which you declare your language support and define the location of the grammar file that has been copied into your extension. +* `syntaxes/ft.tmLanguage.json` - this is the Text mate grammar file that is used for tokenization. +* `language-configuration.json` - this is the language configuration, defining the tokens that are used for comments and brackets. + +## Get up and running straight away + +* Make sure the language configuration settings in `language-configuration.json` are accurate. +* Press `F5` to open a new window with your extension loaded. +* Create a new file with a file name suffix matching your language. +* Verify that syntax highlighting works and that the language configuration settings are working. + +## Make changes + +* You can relaunch the extension from the debug toolbar after making changes to the files listed above. +* You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. + +## Add more language features + +* To add features such as intellisense, hovers and validators check out the VS Code extenders documentation at https://code.visualstudio.com/docs + +## Install your extension + +* To start using your extension with Visual Studio Code copy it into the `/.vscode/extensions` folder and restart Code. +* To share your extension with the world, read on https://code.visualstudio.com/docs about publishing an extension.