Giter Site home page Giter Site logo

remulang / urgent-lang Goto Github PK

View Code? Open in Web Editor NEW
7.0 4.0 1.0 239 KB

The urgent programming language. might not be academic enough or excellent, merely as a better tool for better reasoning things.

License: MIT License

Shell 0.02% Python 99.98%
urgent daily-life

urgent-lang's Introduction

很急语言, 一个"过渡"语言.

安装pip, 命令ugt

(pip install urgent, ugt --help)

运行3.6, 编译3.7

(3.7, 3.8上, urgent编译出的字节码可以被3.6加载, 也就是没有使用ROT4和LOAD_METHOD这些新的指令)

跨版本加载用--raw_bytecode flag.

ugt cc <xxx.ugt> <xxx.code> --raw_bytecode --project bootstrap.toml

后,

import marshal
code_object = marshal.load(open("xxx.code", 'rb'))
exec(code_object, globals())

语句(伪)

  • let/defrec.
let x = 1
def x = 1

一个意思.

  • rec
rec f = x -> (f, x)

是递归, 也就是自己的定义中可以出现自己.

  • let ..., ...
let x = 1, y = 2, z = ...,

定义时x, y, z互不引用, 他们定义时用到的x, y, z来自外部.

  • rec ..., ....
rec x = a -> (a, y), y = a -> (a, x) , z = ...,

定义时, x, y, z互相引用.

If

<expr> ?
    <expr>
else
    <expr>

我觉得语法还行.

how?
  fine
else
  emmm  

还阔以.

Match

let x  =
(1, 2) match
  (a, b, c) => a,
  (1, 2) => 0

可以match的很多, 更多例子见后面的variants.

注意, 二元运算符会被当作解构器.

我们还支持view pattern.

let f = x -> (x, 2 * x)

1 match (f -> (a, b)) => a + b # 1 + 2 * 1 
5 match (f -> (a, b)) => a + b # 5 + 2 * 5 

Open, Import

项目根目录那个hello.ugt可以拿来试, 打开ugt repl,

Urgent> import Hello
Urgent> print 1
Undef print
Urgent> let x = Hello
Urgent> x.print 1
1
Urgent> open x
Urgent> print 1
1

import导入模块但不加载它的成员, open加载成员. 看起来似乎是python的import <mod>from <mod> import *, 其实不是.

一切都是静态的, 只有module可以被import和open. x之所以可以被open, 是因为x被分析为是模块Hello的alias.

Urgent是pure的, 变量不可以多次赋值(只有绑定), 所以, 上面代码里任何使用x的地方都会索引到模块Hello.

如果说python import *是有运行时开销的, 那么, 已经加载过的模块在urgent里, 无论在哪儿open都是0开销的.

一种来自于ML语言的用法是, 在局部打开模块.

Urgent> import Hello
Urgent> let x = 1
Urgent> print 1
Undef print

Urgent> let x = let y = 2 open Hello in print 1
1
Urgent> print 1
Undef print

语句引导的表达式

open, let, rec, def这些语句后面可以跟一个in, 表示表达式.

Urgent> let x = def x = 1 in open Hello in print <| x + 1
2

连续的let, open, 这些语句, 可以不写in.

Urgent> let x = let x = 1 let y = 2 let c = 3 open Hello in print <| x + y + c
6
Urgent> print <| 1 + 2 + 3
Undef operator.<|
Urgent> print (1+2)
Undef operator.+

中缀定义

+左结合,优先级10.

infixl + 10

<|右结合, 优先级0.

infixr <| 0

优先级是一个整数, 可以为负.

如果想要使用其他模块定义的运算符优先级和结合性, 可以open该模块. 如果不想污染作用域, 可以局部open该模块.

只有andor两个是固定的优先级, 他们的优先级都比其他二元运算符低.

andor也用在pattern matching中. and表示左右俩都要match, or表示只match一个.

x match
  1 or 2 or 3 => 0,
  x and (y, z) => (y, x, z) 

Variants

data Nil, Cons(_, _) 
infixr :: 1
let :: = Cons

let l1 = Cons 1 Nil

let print_lst = lst ->
  lst match
    1 :: Cons a b => ...,
    Cons a b => ...,
    Nil =>  ...

[]语法是Nil的简写, [a, b]这样的语法是Cons a (Cons b Nil)的简写, 所以我们可以

data Nil, Cons(_, _) 
infixr :: 1
let :: = Cons
let l1 = [1]

let print_lst = lst ->
  lst match
    1 :: a :: b => ...,
    a :: b => ...,
    [] =>  ...

局部定义的variants:

let x = data A, B, C in
  (A, B, C)
A

# Undef: A

这是用来动态create数据类型的. 注意这对于运行时来说比较缓慢. 一般来说, 还是把数据创建放到模块顶层.

Variants的成员可以按名字访问:

data Either(left, right)
let x = Either(1, 2)
x.left |> print

尾递归

urgent实现了尾递归, 所以, 你可以随意地写递归函数定义.

我们不能说这个速度非常快, 实际上, 比起python循环, 相同情况下我们的尾递归性能只有其一半, 更别说我们还有柯里化.

然而, 既然你在看了, 那我可以开心地向你保证, 这是Python世界最快的, 且货真价实的尾递归实现.

其基本原理相当简单, 你可以在codegen.pypreload方法里找到一个用字节码书写的, 优化到极致的尾递归scheduler.

我会在非尾递归调用点应用这个scheduler, 你能同通过阅读compiler.pyv_tco以及v_call方法, 来进一步理解尾递归优化的实现.

Python函数调用

f.(a, b, c)

像这样, 调用时加个点的函数, 就是按照Python的调用约定. 这并不和我们的尾递归优化冲突.

Imperative Programming

下面的代码需要加载项目目录下的base/prelude.ugt.

  • ref
Urgent> let x = ref 1
=> ()
Urgent> x
=> ref 1
Urgent> x := 2
=> ()
Urgent> x
=> ref 2
Urgent> !x + 2
=> 4
  • for
Urgent> for [1, 2, 3] ( x -> 
  print x
)
1
2
3
=> ()
  • while
Urgent> let x = ref 1
=> ()
Urgent> while { !x < 10 } {
  do print !x
  in x := !x + 1
}

1
2
3
4
5
6
7
8
9
=> ()

上面的循环暂时是尾递归写的, 之后会用Python字节码重写.

forwhile的实现如下:

rec for = seq -> f ->
    seq match
        [] => (),
        hd :: tl =>
            do f hd
            in for tl f

rec while = cond -> f ->
    cond () ?
        do f ()
        in while cond f
    else ()

都可以良好地尾递归.

项目构建

urgent把所有代码编译成单个.pyc文件.

# 编译
sh> ugt cc <主模块.ugt> <a.pyc> --project <项目文件.toml>
# 直接执行
sh> ugt run <主模块.ugt> --project <项目文件.toml>
# 启动REPL
sh> ugt repl --project <项目文件.toml>

一个示例的项目文件见bootstrap.toml.

packaging和project building这些方面其实还没设计好, 但先用着了. 做事第一.

WIP: Traits

urgent-lang's People

Contributors

senzhangai avatar thautwarm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

senzhangai

urgent-lang's Issues

highlighting

随便写写, 能用就行.

%YAML 1.2
---
# See http://www.sublimetext.com/docs/3/syntax.html
file_extensions:
  - ugt
scope: source.urgent

contexts:
  # The prototype context is prepended to all contexts but those setting
  # meta_include_prototype: false.
  prototype:
    - include: comments

  main:
    # The main context is the initial starting point of our syntax.
    # Include other contexts from here (or specify them directly).
    - include: keywords
    - include: numbers
    - include: strings
    - include: operators
    - include: cases

  keywords:
    # Keywords are if, else for and while.
    # Note that blackslashes don't need to be escaped within single quoted
    # strings in YAML. When using single quoted strings, only single quotes
    # need to be escaped: this is done by using two single quotes next to each
    # other.
    - match: '\b(data|match|rec|True|False|and|or|else|for|while|let|def|module|in|infixl|infixr|open|do)\b'
      scope: keyword.control.example-c


  cases:
    - match: '\b[A-Z][a-zA-Z_0-9]*\b'
      scope: entity.name.class

  numbers:
    - match: '\b(-)?[0-9.]+\b'
      scope: constant.numeric.example-c

  operators:
    - match: '->|=>|and|or'
      scope: keyword.operator.haskell

  strings:
    # Strings begin and end with quotes, and use backslashes as an escape
    # character.
    - match: '"'
      scope: punctuation.definition.string.begin.example-c
      push: inside_string

  inside_string:
    - meta_include_prototype: false
    - meta_scope: string.quoted.double.example-c
    - match: '\.'
      scope: constant.character.escape.example-c
    - match: '"'
      scope: punctuation.definition.string.end.example-c
      pop: true

  comments:
    # Comments begin with a '//' and finish at the end of the line.
    - match: '//'
      scope: punctuation.definition.comment.example-c
      push:
        # This is an anonymous context push for brevity.
        - meta_scope: comment.line.double-slash.example-c
        - match: $\n?
          pop: true

import Hello failed

I tried to run examples in README.md, but got an error. :(

Environment

Python version: 3.7

install urgent-lang by:

pip3 install urgent
pip3 install prompt_toolkit

urgent-lang version:

$ pip3 show urgent
Name: urgent
Version: 0.1.1
Summary: UNKNOWN
Home-page: https://github.com/RemuLang/urgent
Author: thautawarm
Author-email: [email protected]
License: mit
Location: /usr/local/lib/python3.7/site-packages
Requires: toml, remu-operator, argser, rbnf-rts, sijuiacion-lang
Required-by:

Error message

# Sen @ Sen in ~/github/urgent-lang on git:master x [15:38:45]
$ ls
LICENSE            build-parser.sh    dev3.py            test               urgent_stmt.exrbnf
README.md          cli.py             hello.ugt          urgent
base               dev.py             mininal_sijuiacion urgent.exrbnf
bootstrap.toml     dev2.py            setup.py           urgent.rlex

# Sen @ Sen in ~/github/urgent-lang on git:master x [15:38:47]
$ ugt repl
Urgent> import Hello
Traceback (most recent call last):
  File "/usr/local/bin/ugt", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.7/site-packages/urgent/cli.py", line 73, in main
    subs.parse()
  File "/usr/local/lib/python3.7/site-packages/argser/parse_func.py", line 136, in parse
    return self.functions[name](**data)
  File "/usr/local/lib/python3.7/site-packages/urgent/repl1s.py", line 59, in repl
    print('=>', eval(code, ctx, ctx))
  File "import Hello", line 11, in <repl>
  File "base", line 1, in tailcall
TypeError: cannot unpack non-iterable module object

narrow the exception types and pretty print exceptions

Currently, the exceptions are not well-rendered, and I just collect the error here,

self._loc = expr.loc
try:
ret = self.dispatches[expr.__class__](self, expr)
return ret
except Report:
,
and do some basic formatting at
except Report as e:
if debug:
traceback.print_exc(limit=tracing_limit)
.

Also, many exceptions raised when compiling are just this simple, without a proper exception type specified:

raise Exception("redefinition of operator properties")

To narrow the exception types, we might create a new module called excs, and make some new exception types in this module, for raising during compilation. The existing exception types might be migrated to excs module.

To pretty print the exceptions, we might create a method in excs to well render the exception to string message.

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.